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 - > не забудьте нажать кнопку применить кнопка внизу для сохранения настроек.