Java8:流 findFirst 结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44458540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java8 : stream findFirst result
提问by Sunflame
I want to know if there is a way to get rid of the warning at findFirst().get()
without using .orElse()
when I know 100% that every time there is a result, so I never get a NoSuchElementException
.
我想知道是否有办法在每次有结果时都知道 100% 时findFirst().get()
无需使用即可消除警告.orElse()
,所以我永远不会得到NoSuchElementException
.
For example let's see the following code:
例如让我们看看下面的代码:
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"
I don't know how other IDEs treat this, but IntelliJ treats that as a warning
我不知道其他 IDE 是如何处理的,但 IntelliJ 将其视为警告
'Optional.get()' without 'isPresent()'
'Optional.get()' 没有 'isPresent()'
I think probably it doesn't know when can you get NoSuchElementException
there and when not, or I have no idea why. I know there are ways to solve this warning(isPresent()
check, .orElse(something)
) but with useless code, so simply I don't want to use those solutions because they are so unnecessary.
我想可能它不知道你什么时候能到NoSuchElementException
,什么时候不能,或者我不知道为什么。我知道有办法解决这个警告(isPresent()
检查,.orElse(something)
)但是使用无用的代码,所以我不想使用这些解决方案,因为它们太不必要了。
Do you have any idea what can I do, or explain how is that treated by the IDE?
你知道我能做什么吗,或者解释一下 IDE 是如何处理的?
采纳答案by Sergii Bishyr
Well, as for me, the best way is to use functional programing and continue to work with optional. So, for example if you need to pass this string to some service, you can do:
嗯,对我来说,最好的方法是使用函数式编程并继续使用可选的。因此,例如,如果您需要将此字符串传递给某个服务,您可以执行以下操作:
String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);
But this looks not so good. Instead you can use the pros of functional programing, and do:
但这看起来不太好。相反,您可以使用函数式编程的优点,并执行以下操作:
myList.stream().findFirst().ifPresent(service::doSomething);
回答by Eugene
First you will not get a NPE
, but a NoSuchElementException
. Second, it's youwho might be sure; but other people might come along and don't realize that it willnot throw an exception.
首先你不会得到一个NPE
,而是一个NoSuchElementException
。其次,你可能有把握;但其他人可能会一起走,并没有意识到这会不会引发异常。
For a sandbox project - yes you would not care and can ignore the warning; for production code I would not disable it (even if you could).
对于沙箱项目 - 是的,您不会关心并且可以忽略警告;对于生产代码,我不会禁用它(即使可以)。
And the last point is that if you are so sure, why not throw an exception?
最后一点是,如果您如此确定,为什么不抛出异常?
orElseThrow(IAmSureThisWillNotHappenException::new)
回答by ΦXoc? ? Пepeúpa ツ
you can stream an empty list without a problem, but if you try to get the 1st element on an empty list you will get a NoSuchElementException
您可以毫无问题地流式传输空列表,但是如果您尝试获取空列表中的第一个元素,您将获得NoSuchElementException
the Stream API is aware of that flawless therefore they offer you multiple ways to handle that:
Stream API 意识到了这一点,因此它们为您提供了多种处理方式:
Option1: orElse
you can return a "default" value if no 1st element is found
选项 1:orElse
如果没有找到第一个元素,您可以返回“默认”值
String firstString = myList.stream().findFirst().orElse("Ups!");
Option2: orElseGet
you can use a Supplier<String>
that gives back a String if no 1st element is found
选项2:如果没有找到第一个元素,orElseGet
您可以使用Supplier<String>
返回字符串的 a
firstString = myList.stream().findFirst().orElseGet(mySupplier);
Option3: orElseThrow
you can throw an exception if no 1st element is found
选项3:orElseThrow
如果找不到第一个元素,您可以抛出异常
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
System.out.println(fisrstString);
回答by holi-java
IFyou know your Optional
never be empty, you can use @SuppressWarnings
annotation as below:
如果您知道自己Optional
永远不会为空,则可以使用@SuppressWarnings
以下注释:
@SuppressWarnings("ConstantConditions") String foo = Optional.of("bar").get();
SometimesOptional.get
will be raising a NullPointerException
, for example:
有时Optional.get
会提高一个NullPointerException
,例如:
Optional<String> it = Optional.empty();
String foo = it.get();
// ^--- throws NullPointerException when this method is invoked
SOwhen this expression is used Intellij will reporting a warnninginspection.
SO当使用这种表达的Intellij将报告一个WARNNING检查。
IFyou want to disable all contract inspection you can do the following actions: Settings-> Inspections-> unchecked the Constant condition & exceptionsoption -> don't forget to click Applybutton at bottom to saving your settings.
如果您想禁用所有合同检查,您可以执行以下操作:设置->检查-> 取消选中常量条件和例外选项 -> 不要忘记单击底部的应用按钮以保存您的设置。
IFyou don't want to disable all contract inspection except Optional.get()
warnnings you can do the following actions: Settings-> Inspections-> checked the Constant condition & exceptionsoption -> at the right bottom side there is a frame to configure Optional.get()
warnnings -> don't forget to click Applybutton at bottom to saving your settings.
如果您不想禁用除Optional.get()
警告之外的所有合同检查,您可以执行以下操作:设置->检查-> 选中常量条件和例外选项 -> 在右下角有一个框架来配置Optional.get()
警告 -> 不不要忘记单击底部的应用按钮来保存您的设置。
回答by Federico Peralta Schaffner
You should make use of the Optional
returned by findFirst()
instead of trying to get its value (if it's actually present).
您应该使用Optional
返回的 byfindFirst()
而不是尝试获取其值(如果它确实存在)。
myList.stream()
.findFirst()
.ifPresent(/* consume the string here, if present */);
The Optional.ifPresent
method receives a Consumer
that will be used only if the Optional
contains a non-null value.
该Optional.ifPresent
方法接收Consumer
只有在Optional
包含非空值时才会使用的。
The problem is that we Java developers are so used to the imperative paradigm... In particular, we are used to getting an object and pushingit i.e. to a method:
问题是我们 Java 开发人员太习惯命令式范式了......特别是,我们习惯于获取一个对象并将它推送到一个方法:
String myString = "hello"; // getting an object here
System.out.println(myString); // pushing the object to System.out here
// (via the println method)
With the Optional
returned by Stream.findFirst()
you were doing the same as above:
随着您Optional
返回Stream.findFirst()
的内容与上述相同:
String myString = myList.stream()
.findFirst()
.get(); // getting a string here
System.out.println(myString); // pushing the string here
On the other hand, the functional paradigm (including Optional
) usually works the other way:
另一方面,函数范式(包括Optional
)通常以另一种方式工作:
myList.stream()
.findFirst()
.ifPresent(myString -> System.out.println(myString));
Here, you don't get the string and then push it to some method. Instead, you provide an argument to Optional
's ifPresent
operation and let the implementation of Optional
push the value to your argument. In other words, you pullthe value wrapped by the Optional
by means of ifPresent
's argument. ifPresent
will then use this Consumer
argument, only if the value is present.
在这里,您没有获得字符串,然后将其推送到某个方法。相反,您为Optional
的ifPresent
操作提供一个参数,并让实现Optional
将值推送到您的参数。换句话说,您通过的参数提取由 包装的值。然后将使用此参数,仅当该值存在时。Optional
ifPresent
ifPresent
Consumer
This pull pattern is seen a lot in functional programming and is very useful, once you get used to it. It just requires us developers to start thinking (and programming) in a different way.
这种拉取模式在函数式编程中很常见,一旦你习惯了它,它就会非常有用。它只是要求我们开发人员以不同的方式开始思考(和编程)。