Java 9 新特性—Stream API的增强

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

为了提高 Stream API 的灵活性和性能,Java 9 对 Stream API 做了一些增强,主要体现在以下几个方法:

  1. 新增 ofNullable()
  2. 重载 iterate()
  3. 新增 dropWhile() 和 takeWhile()

新增 ofNullable()

ofNullable() 用于创建一个 Stream,其中包含一个非空元素或者为空。该方法的主要目的是简化处理可能包含 null 值的集合时的代码,以便避免显式地检查和过滤 null 值。其定义如下:

    public static<T> Stream<T> ofNullable(T t) {
        return t == null ? Stream.empty()
                         : StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
    }

  • 如果参数 t 不为 null,则返回一个包含该非空元素的单元素 Stream。
  • 如果参数 t 为 null,则返回一个空的 Stream。

这就意味着我们可以使用 Stream.ofNullable() 方法来快速创建一个只包含非空元素的 Stream,且无需担心处理 null 值的边界情况。比如,我们有一个 List 包含一些可能为 null 的字符串,我们可以使用 Stream.ofNullable() 来创建一个只包含非空字符串的 Stream:

    @Test
    public void ofNullableTest() {
        List<String> list = Arrays.asList("死磕 Java",null,"死磕 Java 新特性","死磕 Netty",null,null);
        list.stream()
            .flatMap(Stream::ofNullable)
            .forEach(System.out::println);
    }

重载 iterate()

我们知道 Java 8 中的 iterate() 用于创建一个无限流,其元素由给定的初始值和一个生成下一个元素的函数产生,为了终止流我们需要使用一些限制性的函数来操作,例如 limit()

    @Test
    public void iterate() {
        Stream.iterate(1,v -> v + 2)
                .limit(10)
                .forEach(System.out::println);
    }

在 Java 9 中为了限制该无序流的长度,增加了一个谓词,方法定义如下:

static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
  • seed:初始元素,作为序列的第一个元素。
  • hasNext:用于在生成元素时限制序列的长度。如果 hasNext 返回 true,则next 函数就会继续生成下一个元素;一旦 hasNext 返回 false,序列生成将停止。

例如:

    @Test
    public void iterateTest() {
        Stream.iterate(1,n -> n < 20,v -> v + 2)
                .forEach(System.out::println);
    }

当生成的值大于等于 20 时,序列生成就停止。

该重载方法允许我们更加方便地生成元素序列,并在需要时限制序列的长度,这在处理无限序列的情况下非常有用。

新增 dropWhile() 和 takeWhile()

Java 9 引入 dropWhile() 和 takeWhile(),这两个方法允许我们根据谓词条件从流中选择或删除元素,直到遇到第一个不满足条件的元素。

dropWhile() 和 takeWhile(),用于处理流中的前缀元素,而不必处理整个流,为处理 Stream 流提供了更多的灵活性。

dropWhile()

dropWhile() 方法定义如下:

dropWhile(Predicate<? super T> predicate)
  • 方法接受一个 Predicate(谓词)作为参数。
  • 方法会从流的开头开始,跳过满足谓词条件的所有元素,直到找到第一个不满足条件的元素。一旦找到第一个不满足条件的元素,dropWhile() 将停止跳过元素,并返回一个新的流,其中包含了剩余的元素。
  • 如果流的所有元素都满足谓词条件,那么返回一个空流。

示例:

    @Test
    public void dropWhileTest() {
        Stream<Integer> stream = Stream.of(1,2,3,4,5,3,2,6,7,8);
        stream.dropWhile(x -> x < 5)
                .forEach(System.out::println);
    }
    }
// 结果.....
5
3
2
6
7
8

谓词条件 x < 5,即 dropWhile() 会跳过小于 5 的元素, 一旦找到第一个不小于 5 的元素(5),它将停止跳过并返回包含剩余元素的新流(5,3,2,6,7,8)。

takeWhile()

takeWhile() 则与 dropWhile() 相反,它是从流的开头开始,选择满足谓词条件的所有元素,直到找到第一个不满足条件的元素,一旦找到该元素,将会停止选择元素,并返回一个新的流,其中包含了前缀元素。注意两个方法的用词区别,一个是跳过(dropWhile()),一个是选择(takeWhile())。

如果流的所有元素都满足谓词条件,它将返回原始流的一个副本。

示例:

    @Test
    public void takeWhileTest() {
        Stream<Integer> stream = Stream.of(1,2,3,4,5,3,2,6,7,8);
        stream.takeWhile(x -> x < 5)
                .forEach(System.out::println);
    }
// 结果......
1
2
3
4

看到没,同样的示例,只是方法不一样,效果就完全相反。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值