假设,你有一个素数列表,你需要找到第一个大于给定数的素数?你是怎么找到它的?不要告诉您将遍历列表并检查每个元素并返回大于给定数字的第一个元素。嗯,没错,但这不是您在 Java 8 中应该做的事情。这对 Java 7 或更早版本很有好处,但 Java 8 为您提供了许多更好的选择,其中之一就是 Stream。您可以使用 Stream 类以及 filter() 和 findFirst() 方法来查找基于 Predicate 的元素,Predicate 是一个用于定义返回布尔值的条件的功能接口。
java.util.stream.Stream 类提供了两个 find 方法来搜索 Stream 中的元素,findFirst() 和 findAny()。
顾名思义,findFirst 方法返回 Stream 中的第一个元素,包装在 Optional 中,但前提是 Stream 保持顺序,例如从 ArrayList 或 LinkedHashMap 生成的 Stream 保持元素有序。
如果 Stream 不保持顺序,那么任何元素都将返回,这就是 findAny() 方法的作用。它从 Stream 返回一个元素。
这就是为什么如果您再次调用此方法,则不能保证接收到相同的元素。
findFirst() 和 findAny() 都是短路方法,很像短路 AND (&&) 和 OR (||) 运算符,一旦找到一个元素就不会再评估任何元素。
如何使用过滤器从 Stream 中查找第一个元素
现在,让我们回到手头的任务。正如问题陈述所说,我们有一个以递增顺序排列的素数列表,例如2, 3, 5, 7, 11, 13 我们需要找到第一个大于 5 的素数,即我们的代码应该返回 7。
为了实现这一点,我们首先从 List 中获取 Stream,然后调用 number > 7 的 filter() 方法,然后调用 findFirst() 方法。这会给我们结果。
如果您还记得,filter() 是一个中间方法,这意味着在应用过滤器之后,您仍然可以在流上调用其他方法。它也是惰性的,这意味着在您调用诸如 findFirst() 之类的终端方法之前它不会做任何事情。您可以进一步查看 Ranga Karnam 的 Learn Java Functional Programming with Lambdas 和 Stream 课程,以了解有关 Stream 功能的更多信息。
Java 8 流过滤器 + findFirst 示例
以下是应用 predicate 后在 Java 8 中从 List 中查找第一个元素的代码:
package org.hhb.biap.utils;
import java.util.Arrays;
import java.util.List;
/**
*
* A simple example find the first element from List based upon condition.
*
*/
public class FindFirst {
public static void main(String args[]) {
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13);
int primeGreaterThanFive = primes.stream().peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5).findFirst().get();
System.out.println(primeGreaterThanFive);
// Creating a list of Integers
List<Integer> list = Arrays.asList(0, 2, 4, 6, 8, 10);
// Using peek with count() method,Method
// which is a terminal operation
System.out.println("元素个数:" + list.stream().peek(System.out::println).count());
}
}
Output:
will filter 2
will filter 3
will filter 5
will filter 7
7
代码很简单,除了 peek() 和 get() 方法。我已经使用 peek() 来证明 filter 在调用作为终端操作的 findFirst() 方法之前不会执行任何操作。
由于 filter() 是惰性的,它只会处理满足 findFirst() 标准所需的元素,这就是为什么不需要处理所有元素的原因。
可以看到只处理了2、3、5、7返回结果。它没有触及11和13。
如果将条件更改为返回大于 3 的素数,则只会触及 2、3 和 5。如果您正在处理大型列表,例如,这将提供很大的性能提升。有 100 万个数字或字符串的东西。
get() 方法用于从 findFrst() 方法返回的 Optional 中检索一个值。如果你愿意,你也可以使用 OrElse() 方法来定义一个默认值,以防 Optional 为空。
这就是如何从 Java 8 中的 List 或 Stream 中找到满足条件的第一个元素。正如你所看到的,我们可以使用 Predicate 来指定条件,它只是一个函数式接口,只有一个方法 test(),它返回一个布尔值。您可以将它与过滤器等方法一起使用,以在 Java 8 中执行一些有趣的工作。
谷歌翻译:https://www.java67.com/2018/03/java-8-stream-find-first-and-filter-example.html
Peek方法
peek 是中间操作
class Peek { // Main driver method public static void main(String[] args) { // Creating a list of Integers List list = Arrays.asList(0, 2, 4, 6, 8, 10); // Using peek without any terminal // operation does nothing list.stream().peek(System.out::println); } }
没有任何输出。
class Peek { // Main driver method public static void main(String[] args) { // Creating a list of Integers List list = Arrays.asList(0, 2, 4, 6, 8, 10); // Using peek with count() method,Method // which is a terminal operation System.out.println("元素个数:" + list.stream().peek(System.out::println).count()); } }
输出:
0
2
4
6
8
10
元素个数:6
https://www.geeksforgeeks.org/stream-peek-method-in-java-with-examples/
文章评论