认识与理解java中的stream流

系列文章目录

1.SpringBoot整合RabbitMQ并实现消息发送与接收
2. 解析JSON格式参数 & 修改对象的key
3. VUE整合Echarts实现简单的数据可视化
4. List<HashMap<String,String>>实现自定义字符串排序(key排序、Value排序)
5. SpringBoot整合RabbitMQ中交换机的使用(完成消息的发送和接收案例)



前言

       Stream API 是 Java 8 引入的一个用于处理集合数据的新特性。它可以让开发者以一种更函数式、更简洁的方式对集合进行操作,提供了一套丰富的中间操作和终端操作方法,可以实现过滤、映射、归约等操作,同时支持并行处理,提高了代码的可读性和性能。它的特点有很多,例如惰性求值、函数式编程方式、流水线操作、支持并行处理、内置丰富的中间(map、filter等)、终端(collect等)操作方法。
       使用 Stream API 可以简化代码,提高代码的可读性和可维护性。同时,由于其内置的并行处理功能,还可以提高代码的执行效率。在处理集合数据时,特别是需要进行复杂操作或并行处理时,Stream API 是一个非常强大和便捷的工具。下面我们就一起来学习下stream流吧~


一、认识stream流

       在前言中,已经简单的介绍了stream流的一些特点,但大家肯定光去看这写特点的话是没有什么感觉的,下面我们就直接先上一段代码,从代码带入到学习理论知识,一起去深入理解和运用stream流。

1.1 对比

我们知道,在不适用stream的情况下,同样的逻辑也可使用普通的循环去实现。那么我们就是用一个简单的方式来带入一下stream流。

我们要实现一个数组[1,2,4,5]让其每个元素的值加一,返回一个新数组
普通方法实现如下:

private List<Integer> fun2(List<Integer> list) {
        List<Integer> ss = new ArrayList<>();
        for (Integer s : list) {
            ss.add(s+1);
        }
        return ss;
    }

是用stream流实现如下:

private List<Integer> fun1(List<Integer> list) {
        List<Integer> ss=list.stream().map((key)->{
            return key+1;
        }).collect(Collectors.toList());
        return ss;
    }

打印出的效果如下图所示:
在这里插入图片描述
可以看到,最终的效果是一样的,但是究竟有什么区别的。我们在什么场景下使用哪种方式会更加好呢?这里我们就来看下他们的区别。

二、具体的区别

2.1 普通的方式

普通的循环使用于在操作简单遍历,精确控制循环控制时使用。
优点:

  • 直观性: 传统的循环方式更加直观和易于理解,适合处理简单逻辑和少量数据。
  • 精确控制: 可以精确控制循环过程,在一些特殊情况下可能更灵活。
  • 性能优化: 在某些情况下,普通的循环方式可能比Stream API更高效,尤其是对于简单的遍历和操作。

缺点:

  • 冗余代码: 普通的循环方式需要显式地进行迭代和操作,可能会导致代码量增加。
  • 不利于并行处理: 传统循环方式较难实现并行处理,无法充分利用多核处理器的优势。

2.2 stream流

需要对集合数据进行复杂的处理、筛选、转换等操作时,Stream 提供了一种更为简洁、易读和高效的方式。
优点:

  • 函数式编程风格: Stream API提供了函数式编程风格的操作,使代码更加简洁和易读。
  • 链式调用: 可以通过链式调用一系列操作来处理集合元素,减少了中间变量的使用。
  • 内置操作: Stream API提供了丰富的中间操作(如map、filter、sort等)和终端操作(如collect、forEach等),方便进行数据处理和转换。
  • 并行处理: Stream API内置支持并行处理,可以自动将任务分配到多个线程上执行,提高处理效率。

缺点:

  • 学习曲线: 对于初学者来说,可能需要一定时间来熟悉Stream API的概念和操作方式。
  • 性能开销: 在一些情况下,Stream API可能会引入额外的性能开销,尤其是在数据量很大或者处理逻辑复杂的情况下。

三、如何运用stream流

知道了优缺点后,我们来认识下常用的stream流api如何使用,下面我们一个一个理解与结合代码一起学习吧!!!

3.1 filter(Predicate):

作用:过滤符合条件的元素。
案例描述:过滤出长度大于等于 5 的字符串。
输入参数:“apple”, “banana”, “orange”, “pear”, “grape”
输出结果:[apple, banana, orange, grape]
代码如下:

private List<String> fun1(List<String> words) {
        List<String> longWords = words.stream()
                .filter(word -> word.length() >= 5)
                .collect(Collectors.toList());
        return longWords;
    }

3.2 map(Function):

作用:将元素映射为新的元素。
当使用 map 方法时,你需要传入一个 Function 对象,这个对象用于定义元素的映射关系。下面是一个简单的 Java 案例,演示如何使用 map 方法将元素映射为新的元素:

该方法案例在上述对比时的案例中有运用哦
List ss=list.stream().map((key)->{
return key+1;
}).collect(Collectors.toList());

3.3 forEach(Consumer):

作用:对每个元素执行操作。
foreach相信大家已经很熟悉了吧,当使用 forEach 方法时,你需要传入一个 Consumer 对象,这个对象用于定义对每个元素执行的操作。下面是一个简单的 Java 案例,演示如何使用 forEach 方法对集合中的每个元素执行操作:
案例:遍历list

List<String> words = Arrays.asList("apple", "banana", "orange", "pear", "grape");
//使用 forEach 方法对每个元素执行打印操作
words.forEach(System.out::println);

3.4 collect(Collector):

作用:将 Stream 元素收集到集合中。
collect(Collector) 方法是 Stream API 中用于将 Stream 元素收集到集合中的方法。通过 collect 方法,我们可以将 Stream 中的元素按照指定的规则收集到一个集合中,例如 List、Set、Map 等。
这个在上述案例中也运用到过,所以直接上代码:

List<String> longWords = words.stream()
                .filter(word -> word.length() >= 5)
                .collect(Collectors.toList());

3.5 reduce(BinaryOperator):

作用:将 Stream 元素归约为一个值。
reduce(BinaryOperator) 方法是 Stream API 中用于将 Stream 元素归约为一个值的方法。通过 reduce 方法,我们可以对 Stream 中的元素进行累积操作,最终得到一个汇总的结果。

// 创建一个包含整数的 Stream
        Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);

        // 使用 reduce 方法将 Stream 元素相加得到总和
        int sum = numbers.reduce(0, (a, b) -> a + b);

        // 输出归约后的结果
        System.out.println("Sum: " + sum); // 输出 Sum: 15

3.6 distinct():

作用:去重,去除重复元素。
distinct() 是 Stream API 中的一个方法,用于去除重复的元素,保留唯一的元素。当应用在一个 Stream 上时,distinct() 方法会返回一个包含不重复元素的新 Stream。注:一般使用Set集合解决比较好理解。

// 创建一个包含重复元素的 Stream
        Stream<String> stream = Stream.of("apple", "banana", "apple", "orange", "banana");

        // 使用 distinct 方法去除重复元素
        Stream<String> distinctStream = stream.distinct();

        // 输出去重后的元素
        distinctStream.forEach(System.out::println); // 输出 apple, banana, orange

3.7 sorted():

作用:排序,对元素进行排序。
sorted() 方法用于对 Stream 中的元素进行排序,可以使用默认的自然顺序(Comparable 接口)或者自定义排序规则(Comparator 接口)。排序后会返回一个经过排序后的新 Stream。

// 创建一个整数 Stream
        Stream<Integer> numbers = Stream.of(5, 3, 8, 1, 2);

        // 使用 sorted 方法对元素进行排序
        Stream<Integer> sortedStream = numbers.sorted();

        // 输出排序后的元素
        sortedStream.forEach(System.out::println); // 输出 1, 2, 3, 5, 8

3.8 limit(long):

作用:限制结果集的长度。
limit(long) 方法用于限制结果集的长度,只保留指定数量的元素。当应用在一个 Stream 上时,只会返回前面指定数量的元素,后面的元素将被丢弃。

 // 创建一个整数 Stream
        Stream<Integer> numbers = Stream.of(1, 2, 8, 4, 5);

        // 使用 limit 方法限制结果集的长度为3
        Stream<Integer> limitedStream = numbers.limit(3);

        // 输出限制长度后的元素
        limitedStream.forEach(System.out::println); // 输出 1, 2, 8

3.9 skip(long):

作用:跳过指定数量的元素。
skip(long) 方法用于跳过指定数量的元素,返回一个扔掉了前 n 个元素的 Stream。如果 Stream 的长度小于等于 n,则返回一个空 Stream。

// 创建一个整数 Stream
        Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);

        // 使用 skip 方法跳过前面两个元素
        Stream<Integer> skippedStream = numbers.skip(2);

        // 输出跳过元素后的结果
        skippedStream.forEach(System.out::println); // 输出 3, 4, 5

总结

       总的来说,Stream 提供了一种简洁而强大的方式来处理集合数据,它具有函数式编程的特性,能够让我们以声明性的方式进行数据处理操作。对于一些简单的api的使用其实也是比较好理解的,大家在实践中多去运用stream流的方式去处理逻辑,方便熟练运用~
       不知不觉间写文章已经快2年了,断断续续写了90多篇文章。看到大家留言我很开心,也乐意去帮助初学者去更加的深刻理解知识点。按照我的理解简单的去将知识点分享给大家。有问题大家可以联系我哦~我们一起进步

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

心态还需努力呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值