8个你应该掌握的实用 Java Streams API

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

cc0d9803b5a7867e451d6ea3948f2008.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:程序猿DD

274d9ac00ecd396de064a478790d18dd.jpeg


分享8个开箱即用的API,方便日常处理集合。

欢迎关注我的Java新特性专栏:https://www.didispace.com/java-features/

1. 快速过滤空值:Stream.ofNullable

该方法是在 Java 9 中引入的,有助于过滤集合中的所有空值,从而可能使我们避免空指针异常。

在下面的示例中,有一个包含 null 的List。此时,我们可以使用Stream.ofNullable方法对其进行过滤。

List<String> names = Arrays.asList("Alice", null, "Bob", null, "Charlie");
        List<String> nonNuLLNames = names.stream()
        .flatMap(Stream::ofNullable)
        .collect(Collectors.toList());
        System.out.println(nonNuLLNames);

执行上述代码,将输出:

[Alice, Bob, Charlie]

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

2. 流式迭代:Stream.iterate()

Stream.iterate()方法用于创建无限的序列流。它采用种子和一元函数,将函数应用于前一个元素。

在下面的例子中,我们的种子是0,一元运算函数是 n -> n+2。

Stream.iterate(seed: 0, n -> n+2)
        .Limit( maxsize: 10)
        .forEach(e-> {
        System,out printin(e)
        });

执行上述代码,将输出:

0
        2
        4
        6
        8
        10
        12
        14
        16
        18

注意:由于Stream.iterate()生成的是无限序列流。因此我们应该定义终止条件,例如:limit、findFirst 或 findAny 等,以避免无限循环。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

3. 集合转换:collectingAndThen()

collectingAndThen()方法是在 Java 8 中引入的。它是一种特殊的收集器,允许您对另一个收集器的结果执行特殊类型的转换。

在下面的示例中,我们的收集器通过首先使用索引到大写操作进行映射,然后使该映射成为不可修改的Map进行转换。

List<String> fruits = Arrays.asList("apple", "banana","orange");
        Map<Integer, String> result = fruits.stream()
        .collect(Collectors.collectingAndThen(
        Collectors.toMap(fruits::index0f,String::toUpperCase),
        Collections::unmodifiableMap
        ));
        System.out.println(result)

执行上述代码,将输出:

{0=APPLE, 1=BANANA, 2=ORANGE}

4. 删除和截取:dropWhile()takeWhile()

dropWhile()takeWhile()方法是在 java9 中引入的,用于连续处理流。

  • takeWhile():返回符合条件的元素流

  • dropWhile():从元素流中删除符合条件的元素

在下面的示例中,我们删除小于3的元素,然后返回元素小于6的元素流。

List<Integer> numbers = List.of(1,2,3,4,5,6,7);
        numbers.stream()
        .dropWhile(n -> n < 3)
        .takeWhile(n -> n < 6)
        .forEach(System.out::println);

执行上述代码,将输出:

3
        4
        5

5. 整数流:IntStream

IntStream 在 Java 8 中引入,用于快速生成整数流,常用有的以下两个方法:

  • IntStream.range() 方法生成一个整数流,该整数流不包含结尾数字

  • IntStream.rangeClosed() 方法生成一个整数流,该整数流包含结尾数字

下面的例子,可以清晰的看到区别:

// Prints 1,2,3,4
IntStream.range(1,5).forEach(System.out::println);
// Prints 1,2,3,4,5
        IntStream.rangeClosed(1,5).forEach(System.out::println);

6. 应用多个收集器:teeing()

Java 12 中引入的teeing()方法是为了我们可以在元素流上一起应用两个单独的收集器而创建的。

在下面的示例中,我们使用teeing()计算元素流的最大值和最小值,然后将结果以Map形式返回。

Stream<Integer> nums = Stream.of( ...values: 1 2,3 4);
        Map<String, Integer> collect = nums.collect(Collectors.teeing(
        ColLectors.maxBy(Integer::compareTo),
        CoLlectors.minBy(Integer::compareTo),
        (e1, e2) -> Map.of( k1: "min", e1.get(), k2: "max", e2.get())
        ));

        System.out.println(collect);

执行上述代码,将输出:

{max=1, min=4}

7. 合并流:Stream.concat()

Stream.concat()方法可以用来连接两个流并生成一个新流。

Stream<Integer> stream1 = Stream.of(...values: 1,2,3);
        Stream<Integer> stream2 = Stream.of(...values: 4,5,6);
        Stream.concat(stream1, stream2)
        .forEach(System.out::println);

执行上述代码,将输出:

1
        2
        3
        4
        5
        6

8. 分组:Collectors.partitioningBy

Collectors.partitioningBy可以用来对流进行分组。

在下面的示例中,我们根据元素的字符串长度分为两个不同的组。

Map<Boolean, List<String>> result1 = Stream.of(...values: "apple", "banana", "orange", "grape")
        .collect(Collectors.partitioningBy(f -> f.length() > 5));

        System.out.println(result1);

执行上述代码,将输出:

{false=[apple, grape], true=[banana, orange]}

欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

c21987c519cbb99fc999407c58a5cdac.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

21ffcf617e703a00a3e9cefe81ff3ba2.png

83568bcf064ff1c963171acc5ce8a4fc.png1084a89076dd2b5844f5f50e7dd734e7.png42108fd673fa218614689bd212d1be75.png9e6023001cbdaaa0d95f5bd744611a1a.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值