深入浅出stream().findany()

一、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()等操作。

参考资料

1. Stream API RfindAny() 方法文档

2. Stream API findFirst()方法文档

3. FindAny() vs. FindFirst() in Java Streams

4. Java8 – Stream findAny()方法

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/295954.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-27 12:57
下一篇 2024-12-27 12:57

相关推荐

  • 如何使用integratecustomerdata.stream().filter(c->{ if (collectionutil.isnotempty(

    本文将详细介绍如何在Java编程中使用integratecustomerdata.stream().filter(c->{ if (collectionutil.isnote…

    编程 2025-04-28
  • 深入浅出统计学

    统计学是一门关于收集、分析、解释和呈现数据的学科。它在各行各业都有广泛应用,包括社会科学、医学、自然科学、商业、经济学、政治学等等。深入浅出统计学是指想要学习统计学的人能够理解统计…

    编程 2025-04-25
  • C++ Stream详解

    一、从C Stream读取 C Stream是C语言中进行标准输入输出操作的方式。C++在继承C语言的同时也继承了这种方式,通过使用C Stream,我们可以向同一个设备中进行不同…

    编程 2025-04-25
  • 深入浅出torch.autograd

    一、介绍autograd torch.autograd 模块是 PyTorch 中的自动微分引擎。它支持任意数量的计算图,可以自动执行前向传递、后向传递和计算梯度,同时提供很多有用…

    编程 2025-04-24
  • 深入浅出:理解nginx unknown directive

    一、概述 nginx是目前使用非常广泛的Web服务器之一,它可以运行在Linux、Windows等不同的操作系统平台上,支持高并发、高扩展性等特性。然而,在使用nginx时,有时候…

    编程 2025-04-24
  • 深入浅出SQL占位符

    一、什么是SQL占位符 SQL占位符是一种占用SQL语句中某些值的标记或占位符。当执行SQL时,将使用该标记替换为实际的值,并将这些值传递给查询。SQL占位符使查询更加安全,防止S…

    编程 2025-04-24
  • 深入浅出ThinkPHP框架

    一、简介 ThinkPHP是一款开源的PHP框架,它遵循Apache2开源协议发布。ThinkPHP具有快速的开发速度、简便的使用方式、良好的扩展性和丰富的功能特性。它的核心思想是…

    编程 2025-04-24
  • 深入浅出arthas火焰图

    arthas是一个非常方便的Java诊断工具,包括很多功能,例如JVM诊断、应用诊断、Spring应用诊断等。arthas使诊断问题变得更加容易和准确,因此被广泛地使用。artha…

    编程 2025-04-24
  • 深入浅出AWK -v参数

    一、功能介绍 AWK是一种强大的文本处理工具,它可以用于数据分析、报告生成、日志分析等多个领域。其中,-v参数是AWK中一个非常有用的参数,它用于定义一个变量并赋值。下面让我们详细…

    编程 2025-04-24
  • 深入浅出Markdown文字颜色

    一、Markdown文字颜色的背景 Markdown是一种轻量级标记语言,由于其简单易学、易读易写,被广泛应用于博客、文档、代码注释等场景。Markdown支持使用HTML标签,因…

    编程 2025-04-23

发表回复

登录后才能评论