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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:33:05  来源:igfitidea点击:

Java8 : stream findFirst result

javaintellij-ideajava-8java-streamoptional

提问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 NoSuchElementExceptionthere 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: orElseyou can return a "default" value if no 1st element is found

选项 1orElse如果没有找到第一个元素,您可以返回“默认”值

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

Option2: orElseGetyou 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: orElseThrowyou can throw an exception if no 1st element is found

选项3orElseThrow如果找不到第一个元素,您可以抛出异常

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


System.out.println(fisrstString);

回答by holi-java

IFyou know your Optionalnever be empty, you can use @SuppressWarningsannotation as below:

如果您知道自己Optional永远不会为空,则可以使用@SuppressWarnings以下注释:

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

SometimesOptional.getwill 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()警告 -> 不不要忘记单击底部的应用按钮来保存您的设置。

enter image description here

在此处输入图片说明

回答by Federico Peralta Schaffner

You should make use of the Optionalreturned 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.ifPresentmethod receives a Consumerthat will be used only if the Optionalcontains 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 Optionalreturned 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 ifPresentoperation and let the implementation of Optionalpush the value to your argument. In other words, you pullthe value wrapped by the Optionalby means of ifPresent's argument. ifPresentwill then use this Consumerargument, only if the value is present.

在这里,您没有获得字符串,然后将其推送到某个方法。相反,您为OptionalifPresent操作提供一个参数,并让实现Optional将值推送到您的参数。换句话说,您通过的参数提取由 包装的值。然后将使用此参数,仅当该值存在时。OptionalifPresentifPresentConsumer

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.

这种拉取模式在函数式编程中很常见,一旦你习惯了它,它就会非常有用。它只是要求我们开发人员以不同的方式开始思考(和编程)。