Java 中 Stream 流的使用方法

本文详细介绍了JavaStreamAPI的概念、特点,包括Stream的创建方法(如通过Collection、Arrays、接口方法等),中间操作如filter、limit、map等,以及终止操作如min、max、count和collect。帮助读者掌握如何高效地处理集合数据。
摘要由CSDN通过智能技术生成

目录

一、Stream 的概念

二、Stream 的特点

三、Stream 的使用步骤

1、Stream 的创建

        1.1、通过Collection对象的stream()或parallelStream()方法

        1.1.1、stream() 和 parallelStream() 两个方法的区别

        1.2、通过 Arrays 工具类的 stream() 方法

       1.3、通过Stream接口的of()、iterate()、generate()方法。

        1.4、通过IntStream、LongStream、DoubleStream接口中的of、

                range、rangeClosed方法。

2、Stream 的中间操作

        2.1、filter() 过滤操作

        2.2、limit() 截取操作

        2.3、skip() 元素跳过操作

        2.4、distinct() 去重操作

        2.5、sorted() 排序操作

        2.6、map() 对流中元素进行操作

3、Stream 的终止操作

        3.1、min() 和 max() 按照传入的函数获取流中最大最小值

        3.2、count() 获取流中元素个数

        3.3、reduce() 归约操作

        3.4、collect() 将流转换为集合的形式


一、Stream 的概念

流( Stream )与集合类似,但集合中保存的是数据,而 Stream 中保存对集合或数组数据的操作。

二、Stream 的特点

  • Stream 自己不会存储元素。
  • Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream
  • 当一个流执行完终止操作后将不能再被使用。
  • Stream 操作是延迟执行的,会等到需要结果的时候才执行。

三、Stream 的使用步骤

1、Stream 的创建

新建一个流。

        1.1、通过Collection对象的stream()或parallelStream()方法

        //通过Collection对象的stream()或parallelStream()方法。
        List<String> stringList=new ArrayList<>();
        Stream<String> stream1 = stringList.stream();
        Stream<String> stream2 = stringList.parallelStream();
        1.1.1、stream() 和 parallelStream() 两个方法的区别

                stream() 方法:返回一个顺序流,即元素是按顺序处理的。这意味着对于大多数操作,它们将按照集合中元素的顺序依次执行。适合于处理顺序操作,并且在单线程环境下能够提供良好的性能。

               parallelStream() 方法:返回一个并行流,即元素将会在多个线程上同时处理。这意味着对于一些操作,它们可以并行执行,提高处理速度。适合于对大量数据进行并行处理,可以充分利用多核处理器的性能。

        1.2、通过 Arrays 工具类的 stream() 方法

        // 通过Arrays工具类的stream()方法
        int[] arr=new int[10];
        IntStream stream = Arrays.stream(arr);

       1.3、通过Stream接口的of()、iterate()、generate()方法。

        // of() 创建包含指定元素的流
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);

        /*iterate() 生成一个无限长度的流,
        其元素是通过对初始值重复应用指定的函数生成的
        0是初始值,后一个参数为一个函数,初始值为参数*/
        Stream<Integer> iterate = Stream.iterate(0, n -> n + 2);

        /*用于生成一个无限长度的流,
        其中的每个元素是通过调用提供的 Supplier 函数来生成的
        这个流中包含无限个 hello 字符串*/
        Stream<String> generate = Stream.generate(() -> "hello");

        1.4、通过IntStream、LongStream、DoubleStream接口中的of、

                range、rangeClosed方法。

        // of() 创建包含指定元素的流
        IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
        
        // range() 创建指定范围内的所有元素的流(不包含 5)左闭右开
        IntStream range = IntStream.range(1, 5);
        
        // range() 创建指定范围内的所有元素的流(包含 5)
        IntStream closed = IntStream.rangeClosed(1, 5);

2、Stream 的中间操作

在一个或多个步骤中,将初始 Stream 转化到另一个 Stream 的中间操作。

        2.1、filter() 过滤操作

        // filter 过滤操作,参数为一个函数,返回值为 boolean 类型
        Stream<String> stringStream =
                Stream.of("111", "22", "33333", "4444", "5555555","111");
        // 获取流中字符串长度小于3的字符串 结果为 22
        stringStream.filter(o -> o.length() < 3).forEach(System.out::println);

        2.2、limit() 截取操作

        // 获取流中的前两条数据
        stringStream.limit(2).forEach(System.out::println);

        2.3、skip() 元素跳过操作

        // 获取流中第3、4条数据,相当于一个分页操作
        stringStream.skip(2).limit(2).forEach(System.out::println);

        2.4、distinct() 去重操作

        // 去除流中的重复元素
        stringStream.distinct().forEach(System.out::println);

        2.5、sorted() 排序操作

        // 对流中的元素按照字符串长度降序排序
        stringStream.sorted((o1, o2) -> o2.length() - o1.length())

        2.6、map() 对流中元素进行操作

        // 将流中的元素转换为整形,去重并排序(按照默认的排序规则)
        stringStream.map(o -> Integer.parseInt(o)).distinct().sorted();
        // 最简写法,:: 的用法:前面是调用方法的类,后面是要调用的该类的方法
        // 整体含义是调用 Integer 类的 parseInt 方法处理流中的每个元素
        stringStream.map(Integer::parseInt).distinct().sorted();

3、Stream 的终止操作

使用一个终止操作来产生一个结果(新的对象)。该操作会强制之前的延迟操作立即执行,在此之后,该 Stream 就不能使用了

        3.1、min() 和 max() 按照传入的函数获取流中最大最小值

         对于optional 对象的基本使用可以参考Java 中 Optional 类的使用-CSDN博客       

// 获取流中的最小和最大数,返回值为一个 Optional 对象 
Optional<Integer> min = 
stringStream.map(Integer::parseInt).distinct().min((o1, o2) -> o1 - o2);
Optional<Integer> max = 
stringStream.map(Integer::parseInt).distinct().max((o1, o2) -> o1 - o2);

        3.2、count() 获取流中元素个数

        // 获取流中元素的个数
        long count = stringStream.distinct().count();

        3.3、reduce() 归约操作

/*将流中的元素转为整形并 +1,最后进行求和
o1 为第一个参数,o2 为流中的元素*/
stringStream.map(o -> Integer.parseInt(o) + 1).reduce(0, (o1, o2) -> o2);

// 获取流中最大和最小的元素
Optional<Integer> min = stringStream.map(Integer::parseInt).reduce(Integer::max);
Optional<Integer> max = stringStream.map(Integer::parseInt).reduce(Integer::min);

        3.4、collect() 将流转换为集合的形式

@Data
@AllArgsConstructor
@NoArgsConstructor
class Student {
    private Integer Id;
    private String name;
    private Integer age;
    private String hobby;
}
Student s1 = new Student(1, "zs", 20, "唱");
Student s2 = new Student(2, "ls", 21, "唱");
Student s3 = new Student(3, "rose", 22, "跳");
Student s4 = new Student(4, "jack", 20, "rap");
Student s5 = new Student(5, "cxk", 21, "篮球");
// 将流转换为一个 List 集合
List<Student> students = Stream.of(s1, s2, s3, s4, s5).collect(Collectors.toList());
/*将流转换为 map 集合,其中 id 为 key,流中的 Student 元素为 value
toMap中的代码解析:
TradeReportInfo::getTradeId 作为键,o -> o 作为值的生成器函数
(o1, o2) -> o1是一个合并函数,当存在多个具有相同键的对象时,这个函数决定处理这些值*/
Map<Integer, Student> studentMap = Stream.
of(s1, s2, s3,s4,s5).collect(Collectors.toMap(Student::getId, o -> o, (o1, o2) -> o1));

/*将流中的元素根据年龄分组,转换为了一个 map 集合,
其中年龄为 key,value 为该年龄对应的 Student 元素*/
Map<Integer, List<Student>> listMap = Stream.
of(s1, s2, s3, s4, s5).collect(Collectors.groupingBy(Student::getAge));

JavaStream的常用方法包括获取Stream方法和终结方法。 获取Stream方法有两种:集合获取Stream和数组获取Stream。集合获取Stream可以使用集合类的stream()方法,例如Map的keySet()方法可以获取键,values()方法可以获取值,entrySet()方法可以获取键值对。数组获取Stream可以使用Arrays类的stream()方法,将数组转换为Stream方法是对Stream进行操作的方法,一次操作完毕之后,还可以继续进行其他操作。常用的方法包括filter()、map()、flatMap()、distinct()、sorted()、limit()和skip()等。filter()方法用于过滤元素,map()方法用于对元素进行映射,flatMap()方法用于扁平化处理,distinct()方法用于去重,sorted()方法用于排序,limit()方法用于限制元素数量,skip()方法用于跳过元素。 终结方法Stream的最后一个操作,一个Stream只能有一个终结方法。常用的终结方法包括forEach()、collect()、count()、min()、max()、reduce()和toArray()等。forEach()方法用于遍历元素,collect()方法用于将元素收集到集合,count()方法用于统计元素数量,min()方法用于获取最小值,max()方法用于获取最大值,reduce()方法用于对元素进行归约操作,toArray()方法用于将元素转换为数组。 综合应用Stream的常用方法可以实现对数据的筛选、转换、排序、统计等操作,提高代码的简洁性和可读性。 #### 引用[.reference_title] - *1* *2* *3* [Java 基础进阶篇(十二):Stream 常用方法总结](https://blog.csdn.net/weixin_43819566/article/details/130537949)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Double丶11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值