我想知道如果我100%知道每次都有结果,有没有办法摆脱findFirst().get()
警告而不使用.orElse()
,所以我永远不会到达那里{ {1}}。例如,让我们看一下以下代码:
NoSuchElementException
我不知道其他IDE如何对待它,但我的IDE(IntelliJ)将其视为警告( 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"
)。我想可能它不知道你什么时候能得到{'Optional.get()' without 'isPresent()'
1}}那里,什么时候不知道,或者我不知道为什么。我知道有办法解决这个警告(NoSuchElementException
检查,isPresent()
),但有无用的代码,所以我根本不想要使用这些解决方案,因为它们是如此不必要。
你知道我该怎么做,或解释这是怎么回事?
修改:对于NPE,我.orElse(something)
抱歉,我发现了这个错误,但我认为这个问题仍然存在。
答案 0 :(得分:13)
好吧,就我而言,最好的方法是使用功能编程并继续使用可选项。因此,例如,如果您需要将此字符串传递给某个服务,则可以执行以下操作:
String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);
但这看起来并不那么好。相反,你可以使用功能编程的优点,并做:
myList.stream().findFirst().ifPresent(service::doSomething);
答案 1 :(得分:8)
首先,您不会获得NPE
,而是NoSuchElementException
。其次,你可能确定你;但其他人可能会出现并且没有意识到将不会抛出异常。
对于沙盒项目 - 是的,你不会关心,可以忽略警告;对于生产代码,我不会禁用它(即使你可以)。
最后一点是,如果你这么肯定,为什么不抛出异常?
orElseThrow(IAmSureThisWillNotHappenException::new)
答案 2 :(得分:6)
您应该使用Optional
返回的findFirst()
,而不是尝试获取其值(如果它实际存在)。
myList.stream()
.findFirst()
.ifPresent(/* consume the string here, if present */);
Optional.ifPresent
方法会收到仅在Optional
包含非空值时才会使用的Consumer
。
问题在于我们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
的{{1}}操作提供了一个参数,并让ifPresent
的实现将值推送到您的参数中。换句话说,您通过Optional
的参数拉 Optional
包裹的值。只有当值存在时,ifPresent
才会使用此ifPresent
参数。
这种拉动模式在函数式编程中看得很多,并且一旦你习惯它就非常有用。它只需要我们的开发人员以不同的方式开始思考(和编程)。
答案 3 :(得分:3)
你可以毫无问题地流式传输一个空列表,但是如果你试图将第一个元素放在一个空列表中,你将得到一个 NoSuchElementException
Stream API意识到它完美无瑕,因此它们为您提供了多种处理方式:
选项1 :orElse
您可以返回&#34;默认&#34;如果没有找到第一个元素,则为值
String firstString = myList.stream().findFirst().orElse("Ups!");
选项2 :orElseGet
如果找不到第一个元素,您可以使用Supplier<String>
返回字符串
firstString = myList.stream().findFirst().orElseGet(mySupplier);
选项3 :orElseThrow
如果找不到第一个元素,您可以抛出异常
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
System.out.println(fisrstString);
答案 4 :(得分:2)
IF 您知道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
使用此表达式时,SO Intellij将报告警告检查。
如果您要禁用所有合同检查,您可以执行以下操作:设置 - &gt; 检查 - &gt;取消选中常数条件&amp;例外选项 - &gt;不要忘记点击底部的应用按钮保存设置。
如果您不想禁用除Optional.get()
警告之外的所有合同检查,您可以执行以下操作:设置 - &gt; 检查 - &gt;检查恒定条件&amp;例外选项 - &gt;在右下方有一个框架来配置Optional.get()
警告 - &gt;不要忘记点击底部的应用按钮保存设置。