一、stream()简介
Java8引入了Stream API用于处理集合数据,它是集合框架的新成员,允许以一种比传统for/while循环更加声明式和函数化的方式处理数据。它可以对集合数据进行过滤、映射、分组、排序等操作,让开发人员更关注于处理数据本身而不是如何实现操作。
二、stream().findany()与findfirst()
1、基本介绍
在Stream中,findany()和findfirst()都是Terminal Operations,表示Terminal Operation可以结束Stream的操作流程,即终止Stream的生成。
Optional findAny();
Optional findFirst();
findAny() 和 findFirst() 方法都会返回一个 Optional 元素,它代表了这个 Stream 的任意一个元素或第一个元素,并且返回值包含元素可能为 null 的情况。它们的区别在于,前者是并行查找,而后者则不是。
2、性能比较
由于findAny是在并行情况下的任意匹配,的确可以提供更高的并行性,因为在采用该方法时,我们不关心返回的元素是哪一个。只要它符合条件就可以了。
然而,正由于它是任意的,可能会导致生成不同的结果,尤其是在并行处理中,因为在并行处理中,对于一个元素集合,每个线程分配到的元素集合不同,所以结果不一定是固定不变的,但这个影响通常是可接受的。
相比之下,findFirst返回Stream中的第一个元素的确切匹配,正如其名称所示,findFirst()获取流中的第一个元素。在并行流中findFirst在某些情况下会表现出更好的性能,这是因为它不会使用比较大的流进行扫描,只需搜索第一个匹配项即可,而任意匹配只需要比较开头部分的流的部分元素。
总之,如果您不关心返回哪个元素,使用findAny是一个比较好的选择。如果你想要有一种固定的返回值,使用findFirst。
3、代码示例
下面的代码是一个简单的集合的演示,其中我们通过流易语法使用filter()和collect()方法来过滤具有指定物品名称或品牌名称的所有物品对象。接下来,我们使用findFirst()方法获取第一个匹配的元素,然后使用findAny()方法获取任意一个匹配的元素。
public class StreamExample {
public static void main(String[] args) {
//Create a list of items
List<Item> items = new ArrayList<Item>();
items.add(new Item("name1", "brand1"));
items.add(new Item("name2", "brand2"));
items.add(new Item("name3", "brand3"));
items.add(new Item("name4", "brand4"));
items.add(new Item("name5", "brand5"));
items.add(new Item("name6", "brand6"));
//Filter items with given criteria
Item filteredItem = items.stream()
.filter(item -> item.getName().equals("name1"))
.findFirst().orElse(null);
System.out.println("First matching name item : " + filteredItem);
filteredItem = items.stream()
.filter(item -> item.getBrand().equals("brand2"))
.findAny().orElse(null);
System.out.println("Just filtering with brand : " + filteredItem);
}
}
class Item{
private String name;
private String brand;
public Item(String name, String brand) {
this.name = name;
this.brand = brand;
}
public String getName() {
return name;
}
public String getBrand() {
return brand;
}
public String toString() {
return "Name : " + this.name + ", Brand : " + this.brand;
}
}
三、stream().findany()使用场景
1、Stream中anyMatch()
当使用 Stream.anyMatch() 遍历 Stream 时,很可能会使用 findAny() 来判断是否是 true,这种情况下使用 findAny() 可以充分发挥 Stream 的并行优势。当然,这一局限性并不是影响 Stream 效率的唯一因素,我们需要综合考虑每一种操作,并选择最佳方案。
2、Stream中filter()
在 Stream 中使用 filter() + findAny() 可以代替 Stream 中的 findFirst() 方法。它们的结果是相同的,后者的开销较小,前者可能并行处理。
3、Stream中map()
当我们对 Stream 进行处理时,如果使用了 map() 方法,并且不关心返回哪一个元素,那么就可以使用 findAny() 方法来获得任意一个匹配的元素。当然, map() 的返回元素为 int、double 或者 long 基本数据类型时,名为 mapToInt()、mapToDouble() 或 mapToLong() 的方法也可以使用。
4、代码示例
下面的代码演示了我们如何使用findAny()方法在String[]数组中查找任何带有给定名字的人。
import java.util.Optional;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
String[] people = { "Bob", "Alice", "John", "Sarah" };
Optional<String> person = Stream.of(people).filter("John"::equals).findAny();
System.out.println(person.orElse("Not Found"));
}
}
四、stream().findany()总结
stream().findany() 可以用于寻找任意匹配的元素,这个方法可能在并行操作中对性能有所提升。但是这个方法可能对不同的元素集合产生不同的结果。当要求精确的匹配时,可以使用 findFirst() 方法。此外,findAny() 方法还可以用于Stream中anyMatch()、filter()和map()等操作。
参考资料
3. FindAny() vs. FindFirst() in Java Streams
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/295954.html