Java8 : 流查找第一个结果

我想知道是否有办法摆脱警告而不使用,当我知道100%每次都有一个结果,所以我从来没有得到一个.findFirst().get().orElse()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是怎么回事,但IntelliJ把它当作一个警告。

'Optional.get()' 而不带 'isPresent()'

我想可能不知道你什么时候能到达那里,什么时候不可以,或者我不知道为什么。我知道有办法解决这个警告(检查,),但是使用无用的代码,所以我不想使用这些解决方案,因为它们是如此的不必要。NoSuchElementExceptionisPresent().orElse(something)

您知道我能做些什么,或者解释IDE如何处理吗?


答案 1

好吧,对我来说,最好的方法是使用函数式编程并继续使用可选。因此,例如,如果您需要将此字符串传递给某个服务,则可以执行以下操作:

String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);

但这看起来不太好。相反,您可以使用函数式编程的优点,并执行以下操作:

myList.stream().findFirst().ifPresent(service::doSomething);

答案 2

您应该使用返回的 by,而不是尝试获取其值(如果它实际存在)。OptionalfindFirst()

myList.stream()
    .findFirst()
    .ifPresent(/* consume the string here, if present */);

Optional.ifPresent 方法接收一个使用者,仅当 包含非 null 值时才会使用该使用者。Optional

问题是,我们Java开发人员已经习惯了命令式范式......特别是,我们习惯于获取一个对象并将其推送到一个方法:

String myString = "hello"; // getting an object here

System.out.println(myString); // pushing the object to System.out here
                              // (via the println method)

与返回的你正在做与上面相同的操作:OptionalStream.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));

在这里,您不会获取字符串,然后将其推送到某个方法。相反,您为 的操作提供一个参数,并让 的实现将值推送到您的参数。换句话说,您拉取由 by 的参数包装的值。 然后,仅当值存在时,才会使用此参数。OptionalifPresentOptionalOptionalifPresentifPresentConsumer

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


推荐