Определить запись, которая является виновником - практика кодирования - PullRequest
0 голосов
/ 18 июня 2019

Хороша ли цепочка методов?

Я не против функционального программирования, которое часто использует цепочки методов, а против стадного мышления, когда люди бездумно бегут за чем-то новым.

Пример, если я обрабатываю список элементов, используя потоковое программирование, и мне нужно найти точную строку, которая привела к выбрасыванию NullPointerException.

private void test() {
    List<User> aList = new ArrayList<>();
    // fill aList with some data
    aList.stream().forEach(x -> doSomethingMeaningFul(x.getAddress()));
}

private void doSomethingMeaningFul(Address x)   {
     // Do something
}

Так что в приведенном выше примере, если какой-либо объект в списке равен нулю,это приведет к NullPointerException во время вызова x.getAddress() и выйдет, не давая нам возможности определить запись пользователя, у которой есть эта проблема.

Я могу упустить что-то, что предлагает эту функцию в потоковом программировании,приветствуется любая помощь.

Редактировать 1: NPE - только пример, но есть несколько других исключений RuntimeException.Запись фильтра по сути означала бы проверку каждого условия RTE на основе операции, которую я выполняю.И проверка для каждой операции станет болью.

Чтобы дать лучшее представление о том, что я имею в виду, следуя фрагменту, использующему более старые методы;Я не смог найти никакого эквивалента с потоками / методами функционального программирования.

List<User> aList = new ArrayList<>();
// Fill list with some data
int counter = 0;
User u = null;

try {
      for (;counter < aList.size(); counter++) {
          u = aList.get(counter);
          u.doSomething();
          int result = u.getX() / u.getY();
      }
} catch(Exception e)  {
  System.out.println("Error processing at index:" + counter + " with User record:" + u);
  System.out.println("Exception:" + e);
}

This will be a boon during the maintenance phase(longest phase) pointing exact data related issues which are difficult to reproduce.
**Benefits:**
- Find exact index causing issue, pointing to data
- Any RTE is recorded and analyzed against the user record
- Smaller stacktrace to look at

Ответы [ 4 ]

1 голос
/ 18 июня 2019

Является ли метод цепочки хорошим?

Как часто, простой ответ: это зависит.

Когда вы

  • знаю, что ты делаешь
  • будут очень уверены, что элементы никогда не будут нулевыми, таким образом, шанс для NPE в такой конструкции (близок к) 0
  • и цепочка вызовов приводит к улучшению читабельности

тогда конечно, цепные звонки.

Если какой-либо из вышеперечисленных критериев явно не выполняется, подумайте о том, чтобы этого не делать.

В любом случае, может быть полезно распределить вызовы ваших методов по новым строкам. Такие инструменты, как IntelliJ, фактически предоставляют вам расширенную информацию о типе для каждой строки, когда вы делаете это (ну, не всегда, смотрите мой собственный вопрос ;)

С другой точки зрения: для компилятора не имеет большого значения, если вы используете цепочку вызовов. Это действительно имеет значение только для людей. Либо для удобства чтения, либо во время отладки.

0 голосов
/ 18 июня 2019

В этом есть несколько аспектов.

1) Нули

Лучше всего избегать проблемы проверки на нулевые значения, никогда не назначая нулевые. Это относится независимо от того, занимаетесь ли вы функциональным программированием или нет. К сожалению, большая часть кода библиотеки предоставляет возможность возвращать нулевое значение, но старайтесь ограничить воздействие, обрабатывая его в одном месте.

Независимо от того, выполняете ли вы FP или нет, вы обнаружите, что гораздо меньше разочаровываетесь, если вам никогда не придется писать нулевые проверки при вызове ваших собственных методов, потому что ваши собственные методы никогда не могут возвращать null.

Альтернативой переменным, которые могут быть нулевыми, является использование Optional класса Java 8.

Вместо:

public String myMethod(int i) {
     if(i>0) {
          return "Hello";
     } else {
          return null;
     }
}

Do:

public Optional<String> myMethod(int i) {
     if(i>0) {
          return Optional.of("Hello");
     } else {
          return Optional.empty();
}

Посмотрите на Optional Javadoc, чтобы увидеть, как это заставляет звонящего думать о возможности ответа Optional.empty().

Поскольку мост между мирами «ноль означает отсутствие» и «Optional.empty() означает отсутствие», вы можете использовать Optional.ofNullable(val), который возвращает Empty, когда val == null. Но имейте в виду, что Optional.empty() и Optional.of(null) - это разные значения.

2) Исключения

Это правда, что создание исключения в обработчике потока работает не очень хорошо. Исключения не очень дружественный к FP механизм. Подходящая для FP альтернатива - Either - которая не является стандартной частью Java, но ее легко написать самостоятельно или найти в сторонних библиотеках: Есть ли эквивалент Scala's Either в Java 8?

public Either<Exception, Result> meaningfulMethod(Value val) {
    try {
       return Either.right(methodThatMightThrow(val));
    } catch (Exception e) {
       return Either.left(e);
    }
}

... тогда:

List<Either<Exception, Result>> results = listOfValues.stream().map(meaningfulMethod).collect(Collectors.toList());

3) Индексы

Вы хотите знать индекс элемента потока, когда вы используете поток, сделанный из List? См. Есть ли краткий способ перебора потока с индексами в Java 8?

0 голосов
/ 18 июня 2019

Вы можете написать черный код в потоках.И вы можете узнать элемент списка, который может привести к NullPointerException .Я надеюсь, что этот код может помочь

private void test() {
    List<User> aList = new ArrayList<>();
    aList.stream().forEach(x -> {
        if(x.getAddress() != null)
            return doSomethingMeaningFul(x.getAddress())
        else
            system.out.println(x+ "doesn't have address");
    });
}

private void doSomethingMeaningFul(Address x)   {
 // Do something
}

Если вы хотите, вы можете выбросить NullPointerException или пользовательское исключение, например AddressNotFoundException в else часть

0 голосов
/ 18 июня 2019

В вашей функции test () вы создаете пустой список List<User> aList = new ArrayList<>();

и выполняете для каждого из них.Сначала добавьте некоторый элемент в

aList

Если вы хотите обработать нулевые значения, вы можете добавить .filter(x-> x != null), прежде чем foreach будет отфильтровывать все нулевые значения

Ниже приведен код

private void test() {
        List<User> aList = new ArrayList<>();

        aList.stream().filter(x-> x != null).forEach(x -> doSomethingMeaningFul(x.getAddress()));
}

private void doSomethingMeaningFul(Address x)   {
        // Do something
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...