Sun*_*ame 14 java intellij-idea optional java-8 java-stream
我想知道有没有办法摆脱警告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"
Run Code Online (Sandbox Code Playgroud)
我不知道其他IDE如何对待它,但是我的IDE(IntelliJ)将其视为警告('Optional.get()' without 'isPresent()'
).我想可能它不知道你何时可以到达NoSuchElementException
那里,何时不到,或者我不知道为什么.我知道有办法解决这个警告(isPresent()
检查.orElse(something)
),但有无用的代码,所以我不想使用这些解决方案,因为它们是如此不必要.你知道我该怎么做,或解释这是怎么回事?
编辑:对不起NPE,它有NoSuchElementException
我的错误,但我认为这个问题仍然存在.
Ser*_*hyr 14
好吧,对我来说,最好的方法是使用功能编程并继续使用可选项.因此,例如,如果您需要将此字符串传递给某个服务,您可以执行以下操作:
String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);
Run Code Online (Sandbox Code Playgroud)
但这看起来并不那么好.相反,你可以使用功能编程的优点,并做:
myList.stream().findFirst().ifPresent(service::doSomething);
Run Code Online (Sandbox Code Playgroud)
首先你不会得到一个NPE
,但是一个NoSuchElementException
.其次,你可能是肯定的; 但其他人可能出现并没有意识到这会不会引发异常.
对于沙箱项目 - 是的,你不会关心,可以忽略警告; 对于生产代码,我不会禁用它(即使你可以).
最后一点是,如果你这么肯定,为什么不抛出异常呢?
orElseThrow(IAmSureThisWillNotHappenException::new)
Run Code Online (Sandbox Code Playgroud)
您可以毫无问题地流式传输空列表,但是如果您尝试获取空列表中的第一个元素,您将获得NoSuchElementException
Stream API 意识到了这一点,因此它们为您提供了多种处理方式:
选项 1:orElse
如果没有找到第一个元素,您可以返回“默认”值
String firstString = myList.stream().findFirst().orElse("Ups!");
Run Code Online (Sandbox Code Playgroud)
选项2:如果没有找到第一个元素,orElseGet
您可以使用Supplier<String>
返回字符串的 a
firstString = myList.stream().findFirst().orElseGet(mySupplier);
Run Code Online (Sandbox Code Playgroud)
选项3:orElseThrow
如果找不到第一个元素,您可以抛出异常
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
Run Code Online (Sandbox Code Playgroud)
System.out.println(fisrstString);
Run Code Online (Sandbox Code Playgroud)
您应该使用Optional
返回的findFirst()
而不是尝试获取其值(如果它实际存在).
myList.stream()
.findFirst()
.ifPresent(/* consume the string here, if present */);
Run Code Online (Sandbox Code Playgroud)
该Optional.ifPresent
方法接收Consumer
将用来只有当Optional
含有非空值.
问题是我们Java开发人员已经习惯了命令式范例......特别是,我们习惯于获取一个对象并将其推送到一个方法:
String myString = "hello"; // getting an object here
System.out.println(myString); // pushing the object to System.out here
// (via the println method)
Run Code Online (Sandbox Code Playgroud)
随着Optional
返回的Stream.findFirst()
你在做与上面相同:
String myString = myList.stream()
.findFirst()
.get(); // getting a string here
System.out.println(myString); // pushing the string here
Run Code Online (Sandbox Code Playgroud)
另一方面,功能范例(包括Optional
)通常以另一种方式工作:
myList.stream()
.findFirst()
.ifPresent(myString -> System.out.println(myString));
Run Code Online (Sandbox Code Playgroud)
在这里,你没有获得字符串,然后将其推送到某个方法.相反,你提供的参数Optional
的ifPresent
操作,让执行Optional
推价值,你的论点.换句话说,你通过's参数拉出包裹的值.然后,只有当值存在时才会使用此参数.Optional
ifPresent
ifPresent
Consumer
这种拉动模式在函数式编程中很常见,一旦你习惯它就非常有用.它只需要我们的开发人员以不同的方式开始思考(和编程).
归档时间: |
|
查看次数: |
26129 次 |
最近记录: |