Class EasyStream<T>

java.lang.Object
org.miaixz.bus.core.center.stream.EnhancedWrappedStream<T,EasyStream<T>>
org.miaixz.bus.core.center.stream.EasyStream<T>
Type Parameters:
T - 对象类型
All Implemented Interfaces:
AutoCloseable, Iterable<T>, BaseStream<T,Stream<T>>, Stream<T>, TerminableWrappedStream<T,EasyStream<T>>, TransformableWrappedStream<T,EasyStream<T>>, WrappedStream<T,EasyStream<T>>

public class EasyStream<T> extends EnhancedWrappedStream<T,EasyStream<T>>
单元素的扩展流实现。基于原生Stream进行了封装和增强。 作者经对比了vavr、eclipse-collection、stream-ex以及其他语言的api,结合日常使用习惯,进行封装和拓展 Stream为集合提供了一些易用api,它让开发人员能使用声明式编程的方式去编写代码。

中间操作和结束操作

针对流的操作分为分为中间操作结束操作, 流只有在结束操作时才会真正触发执行以往的中间操作中间操作

  • 无状态中间操作: 表示不用等待 所有元素的当前操作执行完 就可以执行的操作,不依赖之前历史操作的流的状态;
  • 有状态中间操作: 表示需要等待 所有元素的当前操作执行完 才能执行的操作,依赖之前历史操作的流的状态;
结束操作
  • 短路结束操作: 表示不用等待 所有元素的当前操作执行完 就可以执行的操作;
  • 非短路结束操作: 表示需要等待 所有元素的当前操作执行完 才能执行的操作;

串行流与并行流

流分为串行流并行流两类:
  • 串行流:针对流的所有操作都会通过当前线程完成;
  • 并行流:针对流的操作会通过拆分器Spliterator拆分为多个异步任务ForkJoinTask执行, 这些异步任务默认使用ForkJoinPool线程池进行管理;
不同类型的流可以通过WrappedStream.sequential()WrappedStream.parallel()互相转换。
Since:
Java 17+
Author:
Kimi Liu
See Also:
  • Method Details

    • builder

      public static <T> EasyStream.Builder<T> builder()
      返回FastStream的建造器
      Type Parameters:
      T - 元素的类型
      Returns:
      a unwrap builder
    • empty

      public static <T> EasyStream<T> empty()
      返回空的串行流
      Type Parameters:
      T - 元素类型
      Returns:
      一个空的串行流
    • of

      public static <T> EasyStream<T> of(T t)
      返回包含单个元素的串行流
      Type Parameters:
      T - 元素类型
      Parameters:
      t - 单个元素
      Returns:
      包含单个元素的串行流
    • of

      @SafeVarargs public static <T> EasyStream<T> of(T... values)
      返回包含指定元素的串行流,若输入数组为null或空,则返回一个空的串行流
      Type Parameters:
      T - 元素类型
      Parameters:
      values - 指定元素
      Returns:
      包含指定元素的串行流 从一个安全数组中创建流
    • of

      public static <T> EasyStream<T> of(Iterable<T> iterable)
      通过实现了Iterable接口的对象创建串行流,若输入对象为null,则返回一个空的串行流
      Type Parameters:
      T - 元素类型
      Parameters:
      iterable - 实现了Iterable接口的对象
      Returns:
    • of

      public static <T> EasyStream<T> of(Iterable<T> iterable, boolean parallel)
      通过传入的Iterable创建流,若输入对象为null,则返回一个空的串行流
      Type Parameters:
      T - 元素类型
      Parameters:
      iterable - Iterable
      parallel - 是否并行
      Returns:
    • of

      public static <T> EasyStream<T> of(Stream<T> stream)
      通过传入的Stream创建流,若输入对象为null,则返回一个空的串行流
      Type Parameters:
      T - 元素类型
      Parameters:
      stream - Stream
      Returns:
    • iterate

      public static <T> EasyStream<T> iterate(T seed, UnaryOperator<T> f)
      返回无限有序流 该流由 初始值 以及执行 迭代函数 进行迭代获取到元素

      例如 FastStream.iterate(0, i -> i + 1) 就可以创建从0开始,每次+1的无限流,使用WrappedStream.limit(long)可以限制元素个数

      Type Parameters:
      T - 元素类型
      Parameters:
      seed - 初始值
      f - 用上一个元素作为参数执行并返回一个新的元素
      Returns:
      无限有序流
    • iterate

      public static <T> EasyStream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
      返回无限有序流 该流由 初始值 然后判断条件 以及执行 迭代函数 进行迭代获取到元素

      例如 FastStream.iterate(0, i -> i < 3, i -> ++i) 就可以创建包含元素0,1,2的流,使用WrappedStream.limit(long)可以限制元素个数

      Type Parameters:
      T - 元素类型
      Parameters:
      seed - 初始值
      hasNext - 条件值
      next - 用上一个元素作为参数执行并返回一个新的元素
      Returns:
      无限有序流
    • iterateHierarchies

      public static <T> EasyStream<T> iterateHierarchies(T root, Function<T,Collection<T>> discoverer, Predicate<T> filter)
      指定一个层级结构的根节点(通常是树或图), 然后获取包含根节点在内,根节点所有层级结构中的节点组成的流。 该方法用于以平铺的方式对图或树节点进行访问,可以使用并行流提高效率。

      eg:

      
       Tree root = // 构建树结构
       // 搜索树结构中所有级别为3的节点,并按权重排序
       List<Tree> thirdLevelNodes = StreamKit.iterateHierarchies(root, Tree:getChildren)
       	.filter(node -> node.getLevel() == 3)
       	.sorted(Comparator.comparing(Tree::getWeight))
       	.toList();
       
      Type Parameters:
      T - 对象类型
      Parameters:
      root - 根节点
      discoverer - 下一层级节点的获取方法
      filter - 节点过滤器,不匹配的节点与以其作为根节点的子树将将会被忽略
      Returns:
      包含根节点在内,根节点所有层级结构中的节点组成的流
    • iterateHierarchies

      public static <T> EasyStream<T> iterateHierarchies(T root, Function<T,Collection<T>> discoverer)
      指定一个层级结构的根节点(通常是树或图), 然后获取包含根节点在内,根节点所有层级结构中的节点组成的流。 该方法用于以平铺的方式对图或树节点进行访问,可以使用并行流提高效率。

      eg:

      
       Tree root = // 构建树结构
       // 搜索树结构中所有级别为3的节点,并按权重排序
       List<Tree> thirdLevelNodes = StreamKit.iterateHierarchies(root, Tree:getChildren)
       	.filter(node -> node.getLevel() == 3)
       	.sorted(Comparator.comparing(Tree::getWeight))
       	.toList();
       
      Type Parameters:
      T - 对象类型
      Parameters:
      root - 根节点
      discoverer - 下一层级节点的获取方法
      Returns:
      包含根节点在内,根节点所有层级结构中的节点组成的流
    • generate

      public static <T> EasyStream<T> generate(Supplier<T> s)
      返回无限串行无序流 其中每一个元素都由给定的Supplier生成 适用场景在一些生成常量流、随机元素等
      Type Parameters:
      T - 元素类型
      Parameters:
      s - 用来生成元素的 Supplier
      Returns:
      无限串行无序流
    • concat

      public static <T> EasyStream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
      创建一个惰性拼接流,其元素是第一个流的所有元素,然后是第二个流的所有元素。 如果两个输入流都是有序的,则结果流是有序的,如果任一输入流是并行的,则结果流是并行的。 当结果流关闭时,两个输入流的关闭处理程序都会被调用。

      从重复串行流进行拼接时可能会导致深度调用链甚至抛出 StackOverflowException

      Type Parameters:
      T - 元素类型
      Parameters:
      a - 第一个流
      b - 第二个流
      Returns:
      拼接两个流之后的流
    • split

      public static EasyStream<String> split(CharSequence text, String regex)
      拆分字符串,转换为串行流
      Parameters:
      text - 字符串
      regex - 正则
      Returns:
      拆分后元素组成的流
    • map

      public <R> EasyStream<R> map(Function<? super T,? extends R> mapper)
      返回与指定函数将元素作为参数执行的结果组成的流 这是一个无状态中间操作
      Type Parameters:
      R - 函数执行后返回的类型
      Parameters:
      mapper - 指定的函数
      Returns:
      返回叠加操作后的流
    • wrap

      public EasyStream<T> wrap(Stream<T> stream)
      根据一个原始的流,返回一个新包装类实例
      Parameters:
      stream - 流
      Returns:
      实现类
    • sum

      public int sum(ToIntFunction<? super T> mapper)
      计算int类型的总和
      Parameters:
      mapper - 将对象转换为int的 Function
      Returns:
      int 总和
    • sum

      public long sum(ToLongFunction<? super T> mapper)
      计算long类型的总和
      Parameters:
      mapper - 将对象转换为long的 Function
      Returns:
      long 总和
    • sum

      public double sum(ToDoubleFunction<? super T> mapper)
      计算double类型的总和
      Parameters:
      mapper - 将对象转换为double的 Function
      Returns:
      double 总和
    • sum

      public <R extends Number> BigDecimal sum(Function<? super T,R> mapper)
      计算 Number 类型的总和
      Type Parameters:
      R - 数字
      Parameters:
      mapper - 将对象转换为NumberFunction
      Returns:
      BigDecimal , 如果流为空, 返回 BigDecimal.ZERO
    • avg

      public Optional<BigDecimal> avg(Function<? super T,BigDecimal> mapper)
      计算 BigDecimal 类型的平均值 并以四舍五入的方式保留2位精度
      Parameters:
      mapper - 将对象转换为BigDecimalFunction
      Returns:
      计算后的平均值 如果流的长度为0, 返回 Optional.empty()
    • avg

      public Optional<BigDecimal> avg(Function<? super T,BigDecimal> mapper, int scale)
      BigDecimal 类型的平均值 并以四舍五入的方式保留小数点后scale位
      Parameters:
      mapper - 将对象转换为BigDecimalFunction
      scale - 保留精度
      Returns:
      计算后的平均值 如果流的长度为0, 返回 Optional.empty()
    • avg

      public Optional<BigDecimal> avg(Function<? super T,BigDecimal> mapper, int scale, RoundingMode roundingMode)
      计算 BigDecimal 类型的平均值
      Parameters:
      mapper - 将对象转换为BigDecimalFunction
      scale - 保留精度
      roundingMode - 舍入模式
      Returns:
      计算后的平均值 如果元素的长度为0 那么会返回 Optional.empty()
    • avg

      public OptionalDouble avg(ToIntFunction<? super T> mapper)
      计算int类型的平均值
      Parameters:
      mapper - 将对象转换为int 的 Function
      Returns:
      OptionalDouble 如果流的长度为0 那么会返回OptionalDouble.empty()
    • avg

      public OptionalDouble avg(ToDoubleFunction<? super T> mapper)
      计算double类型的平均值
      Parameters:
      mapper - 将对象转换为double 的 Function
      Returns:
      OptionalDouble 如果流的长度为0 那么会返回OptionalDouble.empty()
    • avg

      public OptionalDouble avg(ToLongFunction<? super T> mapper)
      计算double平均值
      Parameters:
      mapper - 将对象转换为long 的 Function
      Returns:
      OptionalDouble 如果流的长度为0 那么会返回OptionalDouble.empty()