Stream 接口
1、java.util.stream 中,使用 Stream 接口对集合数据进行操作,类似使用 SQL 执行数据库查询
2、Stream、Collection 区别
(1)Stream:面向 CPU,通过 CPU 计算
(2)Collection:面向内存,一种静态的内存数据结构
事项
1、Stream 不会储存元素
2、Stream 不会改变源对象,相反,Stream 返回一个持有结果的新 Stream
3、Stream 操作是延迟执行的,Stream 会等到需要结果才执行
步骤
1、创建 Stream:一个数据源(如集合、数组),获取一个 Stream 对象
2、中间操作:处理数据源的数据
3、终止操作:一旦执行终止操作,就执行中间操作链,并产生结果,之后,不会再被使用
获取 Stream 方式
1、通过 Collection 接口
(1)返回一个顺序流,此集合作为其来源
default Stream<E> stream()
(2)返回可能并行流,此集合作为其来源,该方法允许返回顺序流
default Stream<E> parallelStream()
2、Arrays 类的 static 方法
(1)返回一个顺序流,指定数组作为源,可以指定开始、结尾索引
public static DoubleStream stream(double[] array)
public static DoubleStream stream(double[] array, int startInclusive, int endExclusive)
public static IntStream stream(int[] array)
public static IntStream stream(int[] array, int startInclusive, int endExclusive)
public static LongStream stream(long[] array)
public static LongStream stream(long[] array, int startInclusive, int endExclusive)
public static <T> Stream<T> stream(T[] array)
public static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive)
3、Stream 类中普通方法
(1)返回指定元素的顺序流
static <T> Stream<T> of(T t)
(2)values 不允许单一 null,而不含其他元素;但可以多个元素,包含 null
static <T> Stream<T> of(T... values)
4、Stream 类中普通方法获取无限流
(1)返回无序无限流,其中每个元素由 Supplier 提供,适合产生恒定流,随机元素流等
static <T> Stream<T> generate(Supplier<T> s)
(2)返回有序无限流
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
中间操作
1、筛选、切片
(1)根据传入的匿名内部类,筛选与 Lambda 表达式不匹配的元素,并返回该 Stream
Stream<T> filter(Predicate<? super T> predicate)
(2)截断该 Stream,并返回,截断长度 <= maxSize
Stream<T> limit(long maxSize)
(3)丢弃该 Stream 前 n 个元素,返回由剩余元素组成的 Stream,若 n >= 原 Stream 元素数量,则返回空 Stream
Stream<T> skip(long n)
(4)根据 hashCode()、equals() 去除重复元素,返回由剩余元素组成的 Stream,若为有序流,则重复元素中保留首个元素;若为无序流,则不能保证稳定性
Stream<T> distinct()
2、映射
(1)对 Stream 中的所有元素应用一对一变换,将元素转为其他形式 / 提取信息,并映射成新元素,所有新元素都整合到一个 Stream 中
<R> Stream<R> map(Function<? super T,? extends R> mapper)
(2)对 Stream 中的所有元素应用一对多变换,将所得到的元素平坦化为新流,即流中每个元素转换为另一个流,然后将所有流连接成一个流
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
3、排序
(1)根据自然顺序排序此流的元素,若为有序流,排序稳定;若为无序流,排序不稳定,元素必须实现 Comparable,否则抛出 java.lang.ClassCastException
Stream<T> sorted()
(2)根据提供的 Comparator 对流中的元素排序,若为有序流,排序稳定;若为无序流,排序不稳定
Stream<T> sorted(Comparator<? super T> comparator)
终止操作
1、匹配、查找
(1)该 Stream 所有元素若匹配传入实现断定型接口的对象 / Stream 为空,返回 true;若有一个元素不匹配,返回 false
boolean allMatch(Predicate<? super T> predicate)
(2)该 Stream 若至少一个元素若匹配,返回 true;若一个都不匹配 / Stream 为空,返回 false
boolean anyMatch(Predicate<? super T> predicate)
(3)该 Stream 所有元素都不匹配 / Stream 为 null,返回 true;若有一个元素匹配,返回 false
boolean noneMatch(Predicate<? super T> predicate)
(4)返回 Stream 第一个元素的 Optional 对象,若 Stream 为空,则返回空的 Optional
Optional<T> findFirst()
(5)返回 Stream 任意一个元素的 Optional 对象,若 Stream 为空,则返回空的 Optional
Optional<T> findAny()
(6)返回此流中的元素数
long count()
(7)根据提供的 Comparator 返回此流的最大元素
Optional<T> max(Comparator<? super T> comparator)
(8)根据提供的 Comparator 返回此流的最小元素
Optional<T> min(Comparator<? super T> comparator)
(9)内部迭代,遍历每个元素执行特定操作
void forEach(Consumer<? super T> action)
(10)Iterable 接口中有集合的外部迭代
default void forEach(Consumer<? super T> action)
2、归约:可以将 Stream 中的元素反复结合
(1)使用 associative 累积函数对此流的元素执行 reduction,若存在差,则返回差的 Optional,若不存在差,抛出 NullPointerException
Optional<T> reduce(BinaryOperator<T> accumulator)
(2)与(1)相似,但多出一个初始值,避免差不存在
T reduce(T identity, BinaryOperator<T> accumulator)
(3)与(2)相似,accumulator:在 U 类型上累积 T 类型,即可以进行类型转换,combiner(结合器)处理并发操作,参数类型必须与返回数据类型一致
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
(4)Stream 支持并发操作,reduce 线程有独立 result,结合器会合并每个线程的 result,得到最终结果
3、收集
(1)将 Stream 转换为其他形式,接收一个 Collector 接口的实现,用于汇总 Stream 元素
<R,A> R collect(Collector<? super T,A,R> collector)
(2)Collector 接口的实现方法决定收集的具体执行
(3)Collectors 类实现 Collector 接口,提供 static 方法,易于创建收集器对象
public static <T> Collector<T,?,List<T>> toList()
public static <T> Collector<T,?,Set<T>> toSet()
public static <T,C extends Collection<T>> Collector<T,?,C> toCollection(Supplier<C> collectionFactory)
并行流、串行流
1、并行流、串行流转换,使用 BaseStream 接口的方法
(1)转换为平行流
S parallel()
(2)转换为顺序流
S sequential()
(3)Stream 类实现 BaseStream 接口
2、解决并行流线程安全问题
(1)同步锁 synchronized
(2)使用线程安全容器,如 Vector
(3)Stream 类,collect 方法、toArray 方法
<R,A> R collect(Collector<? super T,A,R> collector)
<R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
Object[] toArray()
<A> A[] toArray(IntFunction<A[]> generator)
Fork / Join 框架
1、大任务拆分为小任务异步执行
2、模块
(1)线程池:ForkjoinPool
(2)任务对象:ForkjoinTask
(3)执行任务的线程:ForkjoinWorkerThread
3、原理
(1)分治法:任务 Fork 后,任务结果重新 join
(2)工作窃取法:减少窃取线程与被窃取线程之间竞争,采用双端队列,被窃取线程从头部执行任务,窃取线程从尾部执行任务
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战