Java8: поток findFirst результат

Я хочу знать, что есть способ избавиться от предупреждения findFirst().get() без использования .orElse() Если я 100% знаю, что есть каждый раз результат, поэтому я никогда не получаю там NoSuchElementException. Например, давайте посмотрим следующий код:

    List<String> myList = new ArrayList<>();
    myList.add("Test");
    myList.add("Example");
    myList.add("Sth");

    String fisrstString = myList.stream().findFirst().get(); // here I surely get "Test" 

Я не знаю, как другие IDE-s относятся к этому, но моя IDE (IntelliJ) рассматривает это как предупреждение ('Optional.get()' without 'isPresent()').Я думаю, вероятно, он не знает, когда вы можете получить NoSuchElementException там и когда нет, или я понятия не имею, почему.Я знаю, есть способы решить эту проблему. предупреждение(isPresent() проверяем, .orElse(something)) но с бесполезным кодом, поэтому я просто не хочу использовать эти решения, потому что они настолько ненужны. Ты хоть представляешь, что я могу сделать или объяснить, как это лечит Тайд?

Edit: извините за NPE, его NoSuchElementException у меня была эта ошибка, но я думаю, что вопрос все еще доступен для него.

5 ответов


Ну, как и для меня, лучший способ - использовать функциональное программирование и продолжать работать с необязательным. Так, например, если вам нужно передать эту строку какой-то Службе, вы можете сделать:

String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);

но это выглядит не так хорошо. Вместо этого вы можете использовать плюсы функционального программирования и делать:

myList.stream().findFirst().ifPresent(service::doSomething);

сначала вы не получите NPE, но a NoSuchElementException. Во-вторых, это вы кто может быть уверен, но другие люди могут прийти и не понимают, что это будет не исключение.

для проекта песочницы-да, вам все равно и вы можете игнорировать предупреждение; для производственного кода я бы не отключил его (даже если бы вы могли).

и последний момент заключается в том, что если вы так уверены, почему не бросить исключение?

orElseThrow(IAmSureThisWillNotHappenException::new)

вы должны использовать Optional возвращено findFirst() вместо того, чтобы получить его значение (если оно действительно присутствует).

myList.stream()
    .findFirst()
    .ifPresent(/* consume the string here, if present */);

на Optional.ifPresent метод получает Consumer что будет использоваться только если Optional содержит значение, отличное от null.

проблема в том, что мы, разработчики Java, так привыкли к императивной парадигме... В частности, мы привыкли получать объект и толкал это т. е. метод:

String myString = "hello"; // getting an object here

System.out.println(myString); // pushing the object to System.out here
                              // (via the println method)

С Optional возвращено Stream.findFirst() вы делали то же самое, что и выше:

String myString = myList.stream()
    .findFirst()
    .get(); // getting a string here

System.out.println(myString); // pushing the string here

С другой стороны, функциональная парадигма (в том числе Optional) обычно работает по-другому:

myList.stream()
    .findFirst()
    .ifPresent(myString -> System.out.println(myString));

здесь вы не получаете строку, а затем нажимаете ее на какой-то метод. Вместо этого вы предоставляете аргумент Optional ' s ifPresent операция и пусть реализация Optional push значение для вашего аргумента. Другими словами, вы тянуть значение обернутый Optional С помощью 'ы. ifPresent затем будет использовать это


вы можете передавать пустой список без проблем, но если вы попытаетесь получить 1-й элемент в пустом списке, вы получите NoSuchElementException

API потока знает об этом безупречном, поэтому они предлагают вам несколько способов справиться с этим:

Option1: orElse вы можете вернуть значение "по умолчанию", если не найден 1-й элемент

String firstString = myList.stream().findFirst().orElse("Ups!");

Option2: orElseGet можно использовать Supplier<String> что дает обратно Строка, если 1-й элемент не найден

firstString = myList.stream().findFirst().orElseGet(mySupplier);

Вариант 3: orElseThrow вы можете создать исключение, если 1-й элемент не найден

firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);

System.out.println(fisrstString);

если вы знаете, что ваш Optional никогда не быть пустым, вы можете использовать @SuppressWarnings аннотации, как показано ниже:

@SuppressWarnings("ConstantConditions") String foo = Optional.of("bar").get();

иногда Optional.get будет поднимать NullPointerException, например:

Optional<String> it = Optional.empty();
String foo = it.get();
          //   ^--- throws NullPointerException when this method is invoked

так при использовании этого выражения Intellij будет сообщать warnning проверка.

если вы хотите отключить все проверки контракта вы можете сделать следующие действия: настройки ->инспекции -> снят постоянное состояние и исключения опция - > не забудьте нажать применить кнопка внизу для сохранения настроек.

если вы не хотите отключать все проверки контрактов, кроме Optional.get() warnnings вы можете сделать следующие действия: настройки ->инспекции -> проверил постоянное состояние и исключения -> в правой нижней части есть рамка для настройки Optional.get() warnnings - > не забудьте нажать кнопку применить кнопка внизу для сохранения настроек.

enter image description here