Stream
的findAny
方法选择该流中的任何元素。
findAny
方法的行为是不确定的,它可以自由选择流中的任何元素。
findAny
方法有助于在并行操作中获得最大的性能,但它不能保证每次调用都得到相同的结果。
在java doc
中的findAny()
方法声明
Optional<T> findAny()
上述方法返回java.util.Optional
,一个容器对象,可能包含也可能不包含非空值。
当方法在流中选择null
值时,findAny
抛出NullPointerException
。
如果每次都要选择第一个元素,请使用Stream
的findFirst()
方法。
下面是findAny
的示例。
示例1
假设我们有一个整数流。
Stream.of(10, 20, 30).findAny()
.ifPresent(s -> System.out.println(s));
此执行在一般情况下,并不会随机输出,而是按顺序输出,因为该流是有顺序的串行流,按照最优执行会按照顺序,感谢静夜的DD大佬的指出。
如果我们想要看到随机选择,需要改成并行流。
Stream.of(10, 20, 30).parallel().findAny()
.ifPresent(s -> System.out.println(s));
再次调用findAny
方法时,可以自由选择流中的任何元素,这意味着findAny
可以给出10、20或30的输出。
注:
findAny
不是为了随机而随机,而是为了进行最快速的选择,所以最好不要用在随机选择的场景。
再看一组例子
FindAnyDemo1.java
package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class FindAnyDemo1 {
public static void main(String[] args) {
List<String> list = Arrays.asList("Mahesh", "Suresh", "Mohit");
String output = list.stream()
.filter(e -> e.startsWith("M"))
.findAny()
.orElse("NA");
System.out.println(output);
List<Integer> numList = Arrays.asList(21, 22, 23, 24);
numList.stream()
.filter(n -> n % 2 == 0)
.findAny()
.ifPresent(e -> System.out.println(e));
}
}
输出
Mahesh
22
查看上面的代码行
list.stream().filter(e -> e.startsWith("M"))
过滤后流中包含“Mahesh”、“Mohit”。findAny
可以自由选择其中任何一个。所以,如果我们多次运行这个例子,输出并不一定每次都相同。
示例2
下面是使用IntStream
、LongStream
和DoubleStream
的findAny
方法示例。
FindAnyDemo2.java
package com.concretepage;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class FindAnyDemo2 {
public static void main(String[] args) {
IntStream intStream = IntStream.of(10, 20, 30, 40);
intStream.filter(i -> i > 20).findAny()
.ifPresent(i -> System.out.println(i));
LongStream longStream = LongStream.of(100, 200, 300);
longStream.filter(l -> l < 250).findAny()
.ifPresent(l -> System.out.println(l));
DoubleStream doubleStream = DoubleStream.of(100.52, 200.55, 300.66);
doubleStream.filter(d -> d > 200).findAny()
.ifPresent(l -> System.out.println(l));
}
}
输出
30
100
200.55
示例3
findAny
方法提高了并行流的性能,但我们要知道,重新运行时输出可能会有所不同。
FindAnyDemo3.java
package com.concretepage;
import java.util.ArrayList;
import java.util.List;
public class FindAnyDemo3 {
public static void main(String[] args) {
List<Employee> list = new ArrayList<>();
list.add(new Employee("Emp A", 3000));
list.add(new Employee("Emp B", 4000));
list.add(new Employee("Emp C", 5000));
list.add(new Employee("Emp D", 6000));
list.parallelStream()
.filter(e -> e.getSal() >= 4000 && e.getSal() <= 5000)
.mapToInt(e -> e.getSal())
.findAny()
.ifPresent(s -> System.out.println(s));
}
}
class Employee {
private String name;
private int sal;
public Employee(String name, int sal) {
this.name = name;
this.sal = sal;
}
//Sets and Gets
}
输出
5000
示例4
如果findAny
方法选择null
值,则抛出NullPointerException
。
FindAnyDemo4.java
package com.concretepage;
import java.util.stream.Stream;
public class FindAnyDemo4 {
public static void main(String[] args) {
Stream.of(null, "AA").
findAny().ifPresent(s -> System.out.println(s));
}
}
输出将为NullPointerException
。