模块 java.base

接口 Stream<T>

类型参数:
T - 流元素的类型
所有父级接口:
AutoCloseable , BaseStream<T,Stream<T>>

public interface Stream<T> extends BaseStream <T,Stream <T>>
支持顺序和并行聚合操作的元素序列。以下示例说明了使用 Stream IntStream 的聚合操作:

   int sum = widgets.stream()
           .filter(w -> w.getColor() == RED)
           .mapToInt(w -> w.getWeight())
           .sum();
  
在此示例中,widgetsCollection<Widget>。我们通过 Collection.stream() 创建一个 Widget 对象流,对其进行过滤以生成仅包含红色小部件的流,然后将其转换为代表每个红色小部件权重的 int 值流。然后将此流相加以产生总重量。

除了对象引用流 Stream 之外,还有 IntStream LongStream DoubleStream 的原始特化,所有这些都称为“流”并符合此处描述的特征和限制。

为了执行计算,流 操作 被组合成一个 stream pipeline 。流管道由源(可能是数组、集合、生成器函数、I/O 通道等)、零个或多个 intermediate operations(将一个流转换为另一个流,例如 filter(Predicate) )和一个terminal operation(产生结果或副作用,例如 count() forEach(Consumer) )。流是懒惰的;仅在启动终端操作时才对源数据进行计算,并且仅在需要时使用源元素。

允许流实现在优化结果计算方面有很大的自由度。例如,流实现可以自由地从流管道中省略操作(或整个阶段)——因此省略行为参数的调用——如果它可以证明它不会影响计算结果。这意味着行为参数的副作用可能并不总是被执行并且不应被依赖,除非另有说明(例如通过终端操作 forEachforEachOrdered )。 (有关此类优化的具体示例,请参阅记录在 count() 操作上的 API 说明。有关更多详细信息,请参阅流包文档的 副作用 部分。)

集合和流虽然具有一些表面上的相似性,但具有不同的目标。集合主要关注对其元素的有效管理和访问。相比之下,流不提供直接访问或操作其元素的方法,而是关注以声明方式描述其源以及将在该源上聚合执行的计算操作。但是,如果提供的流操作不提供所需的功能,BaseStream.iterator() BaseStream.spliterator() 操作可用于执行受控遍历。

流管道,如上面的“小部件”示例,可以被视为流源上的 query。除非源明确设计用于并发修改(例如 ConcurrentHashMap ),否则在查询流源时修改流源可能会导致不可预测或错误的行为。

大多数流操作接受描述用户指定行为的参数,例如上例中传递给 mapToInt 的 lambda 表达式 w -> w.getWeight()。为了保持正确的行为,这些 behavioral parameters

  • 必须是不干扰(他们不修改流源);和
  • 在大多数情况下必须是 无国籍的(它们的结果不应该依赖于流管道执行期间可能改变的任何状态)。

此类参数始终是 功能接口 的实例,例如 Function ,并且通常是 lambda 表达式或方法引用。除非另有说明,否则这些参数必须是 non-null

流应该只被操作一次(调用中间或终端流操作)。这排除了,例如,“分叉”流,其中相同的源提供两个或多个管道,或同一流的多次遍历。如果流实现检测到流被重用,它可能会抛出 IllegalStateException 。但是,由于某些流操作可能会返回它们的接收器而不是新的流对象,因此可能无法在所有情况下检测到重用。

流有一个 BaseStream.close() 方法并实现 AutoCloseable 。在流关闭后对其进行操作将抛出 IllegalStateException 。大多数流实例在使用后实际上不需要关闭,因为它们由集合、数组或生成函数支持,不需要特殊的资源管理。通常,只有源为 IO 通道的流(例如 Files.lines(Path) 返回的流)才需要关闭。如果流确实需要关闭,则必须在 try-with-resources 语句或类似的控制结构中将其作为资源打开,以确保在其操作完成后立即将其关闭。

流管道可以按顺序执行或在 parallel 中执行。这种执行模式是流的一个属性。流是在最初选择顺序执行或并行执行的情况下创建的。 (例如,Collection.stream() 创建一个顺序流,Collection.parallelStream() 创建一个并行流。)这种执行模式的选择可以通过 BaseStream.sequential() BaseStream.parallel() 方法进行修改,并且可以使用 BaseStream.isParallel() 方法进行查询。

自从:
1.8
参见:
  • 内部类总结

    内部类
    修饰符和类型
    接口
    描述
    static interface 
    Stream 的可变构建器。
  • 方法总结

    修饰符和类型
    方法
    描述
    boolean
    allMatch(Predicate<? super T> predicate)
    返回此流的所有元素是否与提供的谓词匹配。
    boolean
    anyMatch(Predicate<? super T> predicate)
    返回此流的任何元素是否与提供的谓词匹配。
    static <T> Stream.Builder<T>
    返回 Stream 的构建器。
    <R> R
    collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
    对此流的元素执行 可变减少 操作。
    <R, A> R
    collect(Collector<? super T,A,R> collector)
    使用 Collector 对此流的元素执行 可变减少 操作。
    static <T> Stream<T>
    concat(Stream<? extends T> a, Stream<? extends T> b)
    创建一个惰性串联流,其元素是第一个流的所有元素,后跟第二个流的所有元素。
    long
    返回此流中元素的计数。
    返回由该流的不同元素(根据 Object.equals(Object) )组成的流。
    default Stream<T>
    dropWhile(Predicate<? super T> predicate)
    如果此流是有序的,则返回一个流,该流由删除与给定谓词匹配的元素的最长前缀后的此流的剩余元素组成。
    static <T> Stream<T>
    返回一个空的顺序 Stream
    filter(Predicate<? super T> predicate)
    返回一个流,该流由与给定谓词匹配的此流的元素组成。
    返回描述流中某些元素的 Optional ,如果流为空,则返回空的 Optional
    返回描述此流的第一个元素的 Optional ,如果流为空,则返回空的 Optional
    <R> Stream<R>
    flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
    返回一个流,该流由将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容组成的结果。
    flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
    返回一个 DoubleStream ,其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。
    flatMapToInt(Function<? super T,? extends IntStream> mapper)
    返回一个 IntStream ,其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。
    flatMapToLong(Function<? super T,? extends LongStream> mapper)
    返回一个 LongStream ,由将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容组成的结果。
    void
    forEach(Consumer<? super T> action)
    对此流的每个元素执行一个操作。
    void
    forEachOrdered(Consumer<? super T> action)
    如果流具有已定义的遇到顺序,则按照流的遇到顺序为此流的每个元素执行操作。
    static <T> Stream<T>
    generate(Supplier<? extends T> s)
    返回无限顺序无序流,其中每个元素都由提供的 Supplier 生成。
    static <T> Stream<T>
    iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
    返回由给定的 next 函数迭代应用到初始元素而产生的顺序有序的 Stream,条件是满足给定的 hasNext 谓词。
    static <T> Stream<T>
    iterate(T seed, UnaryOperator<T> f)
    返回由函数 f 迭代应用到初始元素 seed 产生的无限顺序有序 Stream,产生由 seedf(seed)f(f(seed)) 等组成的 Stream
    limit(long maxSize)
    返回由该流的元素组成的流,截断后的长度不超过 maxSize
    <R> Stream<R>
    map(Function<? super T,? extends R> mapper)
    返回一个流,该流由将给定函数应用于此流的元素的结果组成。
    default <R> Stream<R>
    mapMulti(BiConsumer<? super T,? super Consumer<R>> mapper)
    返回一个流,该流由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。
    default DoubleStream
    mapMultiToDouble(BiConsumer<? super T,? super DoubleConsumer> mapper)
    返回一个 DoubleStream,由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。
    default IntStream
    mapMultiToInt(BiConsumer<? super T,? super IntConsumer> mapper)
    返回一个 IntStream,由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。
    default LongStream
    mapMultiToLong(BiConsumer<? super T,? super LongConsumer> mapper)
    返回一个 LongStream,由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。
    mapToDouble(ToDoubleFunction<? super T> mapper)
    返回一个 DoubleStream,由将给定函数应用于此流的元素的结果组成。
    mapToInt(ToIntFunction<? super T> mapper)
    返回一个 IntStream,由将给定函数应用于此流的元素的结果组成。
    mapToLong(ToLongFunction<? super T> mapper)
    返回一个 LongStream,由将给定函数应用于此流的元素的结果组成。
    max(Comparator<? super T> comparator)
    根据提供的 Comparator 返回此流的最大元素。
    min(Comparator<? super T> comparator)
    根据提供的 Comparator 返回此流的最小元素。
    boolean
    noneMatch(Predicate<? super T> predicate)
    返回此流中是否没有元素与提供的谓词匹配。
    static <T> Stream<T>
    of(T t)
    返回包含单个元素的顺序 Stream
    static <T> Stream<T>
    of(T... values)
    返回其元素为指定值的顺序有序流。
    static <T> Stream<T>
    ofNullable(T t)
    返回包含单个元素的顺序 Stream(如果非空),否则返回空的 Stream
    peek(Consumer<? super T> action)
    返回一个由该流的元素组成的流,当从结果流中消耗元素时,还会对每个元素执行提供的操作。
    reduce(BinaryOperator<T> accumulator)
    使用 联想的 累加函数对此流的元素执行 减少,并返回描述减少值(如果有)的 Optional
    T
    reduce(T identity, BinaryOperator<T> accumulator)
    使用提供的标识值和 联想的 累加函数对此流的元素执行 减少,并返回减少的值。
    <U> U
    reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
    使用提供的标识、累积和组合函数对此流的元素执行 减少
    skip(long n)
    在丢弃流的前 n 个元素后,返回由该流的剩余元素组成的流。
    返回一个流,该流由该流的元素组成,并按自然顺序排序。
    sorted(Comparator<? super T> comparator)
    返回由该流的元素组成的流,根据提供的 Comparator 排序。
    default Stream<T>
    takeWhile(Predicate<? super T> predicate)
    如果此流是有序的,则返回一个流,该流由从此流中获取的与给定谓词匹配的元素的最长前缀组成。
    返回包含此流的元素的数组。
    <A> A[]
    toArray(IntFunction<A[]> generator)
    返回一个包含此流元素的数组,使用提供的 generator 函数分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。
    default List<T>
    将此流的元素累积到 List 中。

    在接口 java.util.stream.BaseStream 中声明的方法

    close, isParallel, iterator, onClose, parallel, sequential, spliterator, unordered
  • 方法详情

    • filter

      Stream <T > filter(Predicate <? super T > predicate)
      返回一个流,该流由与给定谓词匹配的此流的元素组成。

      这是一个 中间操作

      参数:
      predicate - 一个 不干扰 , 无国籍的 谓词应用于每个元素以确定是否应包含它
      返回:
      新流
    • map

      <R> Stream <R> map(Function <? super T ,? extends R> mapper)
      返回一个流,该流由将给定函数应用于此流的元素的结果组成。

      这是一个 中间操作

      类型参数:
      R - 新流的元素类型
      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于每个元素
      返回:
      新流
    • mapToInt

      IntStream  mapToInt(ToIntFunction <? super T > mapper)
      返回一个 IntStream,由将给定函数应用于此流的元素的结果组成。

      这是一个 中间操作

      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于每个元素
      返回:
      新流
    • mapToLong

      LongStream  mapToLong(ToLongFunction <? super T > mapper)
      返回一个 LongStream,由将给定函数应用于此流的元素的结果组成。

      这是一个 中间操作

      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于每个元素
      返回:
      新流
    • mapToDouble

      DoubleStream  mapToDouble(ToDoubleFunction <? super T > mapper)
      返回一个 DoubleStream,由将给定函数应用于此流的元素的结果组成。

      这是一个 中间操作

      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于每个元素
      返回:
      新流
    • flatMap

      <R> Stream <R> flatMap(Function <? super T ,? extends Stream <? extends R>> mapper)
      返回一个流,该流由将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容组成的结果。每个映射流在其内容被放入该流后都是closed 。 (如果map流是null,则使用空流。)

      这是一个 中间操作

      API 注意:
      flatMap() 操作的作用是对流的元素应用一对多转换,然后将生成的元素展平为新流。

      例子。

      如果 orders 是一个采购订单流,并且每个采购订单都包含一个订单项集合,那么以下将生成一个包含所有订单中所有订单项的流:

      
         orders.flatMap(order -> order.getLineItems().stream())...
        

      如果 path 是文件的路径,则以下内容会生成该文件中包含的 words 的流:

      
         Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
         Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
        
      传递给 flatMapmapper 函数使用简单的正则表达式将一行拆分为单词数组,然后从该数组创建单词流。
      类型参数:
      R - 新流的元素类型
      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于产生新值流的每个元素
      返回:
      新流
      参见:
    • flatMapToInt

      IntStream  flatMapToInt(Function <? super T ,? extends IntStream > mapper)
      返回一个 IntStream ,其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射流在其内容被放入该流后都是closed 。 (如果map流是null,则使用空流。)

      这是一个 中间操作

      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于产生新值流的每个元素
      返回:
      新流
      参见:
    • flatMapToLong

      LongStream  flatMapToLong(Function <? super T ,? extends LongStream > mapper)
      返回一个 LongStream ,由将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容组成的结果。每个映射流在其内容被放入该流后都是closed 。 (如果map流是null,则使用空流。)

      这是一个 中间操作

      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于产生新值流的每个元素
      返回:
      新流
      参见:
    • flatMapToDouble

      DoubleStream  flatMapToDouble(Function <? super T ,? extends DoubleStream > mapper)
      返回一个 DoubleStream ,其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射流在其内容放入此流后都是closed 。 (如果map流是null,则使用空流。)

      这是一个 中间操作

      参数:
      mapper - 一个 不干扰 , 无国籍的 函数应用于产生新值流的每个元素
      返回:
      新流
      参见:
    • mapMulti

      default <R> Stream <R> mapMulti(BiConsumer <? super T ,? super Consumer <R>> mapper)
      返回一个流,该流由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。通过将提供的映射函数与接受替换元素的consumer参数一起应用于每个元素来执行替换。映射函数零次或多次调用消费者以提供替换元素。

      这是一个 中间操作

      如果 consumer 参数在其映射函数的应用范围之外使用,则结果未定义。

      API 注意:
      此方法与 flatMap 类似,因为它将一对多转换应用于流的元素并将结果元素展平为新流。在以下情况下,此方法优于 flatMap
      • 当用少量(可能为零)元素替换每个流元素时。使用此方法可以避免为每组结果元素创建新 Stream 实例的开销,如 flatMap 所要求的那样。
      • 当使用命令式方法生成结果元素比以流的形式返回它们更容易时。

      如果提供 lambda 表达式作为映射器函数参数,则可能需要额外的类型信息才能正确推断返回流的元素类型 <R>。这可以以 lambda 参数的显式类型声明的形式或作为 mapMulti 调用的显式类型参数的形式提供。

      示例

      给定一个 Number 对象流,以下生成一个仅包含 Integer 对象的列表:

      
         Stream<Number> numbers = ... ;
         List<Integer> integers = numbers.<Integer>mapMulti((number, consumer) -> {
             if (number instanceof Integer i)
               consumer.accept(i);
           })
           .collect(Collectors.toList());
        

      如果我们有一个 Iterable<Object> 并且需要递归扩展它本身属于 Iterable 类型的元素,我们可以使用 mapMulti 如下:

      
       class C {
         static void expandIterable(Object e, Consumer<Object> c) {
           if (e instanceof Iterable<?> elements) {
             for (Object ie : elements) {
               expandIterable(ie, c);
             }
           } else if (e != null) {
             c.accept(e);
           }
         }
      
         public static void main(String[] args) {
           var nestedList = List.of(1, List.of(2, List.of(3, 4)), 5);
           Stream<Object> expandedStream = nestedList.stream().mapMulti(C::expandIterable);
         }
       }
        
      实现要求:
      默认实现在此流上调用 flatMap ,传递一个行为如下的函数。首先,它使用 Consumer 调用映射器函数,将替换元素累积到新创建的内部缓冲区中。当映射器函数返回时,它从内部缓冲区创建一个流。最后,它将这个流返回给 flatMap
      类型参数:
      R - 新流的元素类型
      参数:
      mapper - 生成替换元素的 不干扰无国籍的 函数
      返回:
      新流
      自从:
      16
      参见:
    • mapMultiToInt

      default IntStream  mapMultiToInt(BiConsumer <? super T ,? super IntConsumer > mapper)
      返回一个 IntStream,由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。通过将提供的映射函数与接受替换元素的consumer参数一起应用于每个元素来执行替换。映射函数零次或多次调用消费者以提供替换元素。

      这是一个 中间操作

      如果 consumer 参数在其映射函数的应用范围之外使用,则结果未定义。

      实现要求:
      默认实现在此流上调用 flatMapToInt ,传递一个行为如下的函数。首先,它使用 IntConsumer 调用映射器函数,将替换元素累积到新创建的内部缓冲区中。当映射器函数返回时,它会从内部缓冲区创建一个IntStream。最后,它将这个流返回给 flatMapToInt
      参数:
      mapper - 生成替换元素的 不干扰无国籍的 函数
      返回:
      新流
      自从:
      16
      参见:
    • mapMultiToLong

      default LongStream  mapMultiToLong(BiConsumer <? super T ,? super LongConsumer > mapper)
      返回一个 LongStream,由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。通过将提供的映射函数与接受替换元素的consumer参数一起应用于每个元素来执行替换。映射函数零次或多次调用消费者以提供替换元素。

      这是一个 中间操作

      如果 consumer 参数在其映射函数的应用范围之外使用,则结果未定义。

      实现要求:
      默认实现在此流上调用 flatMapToLong ,传递一个行为如下的函数。首先,它使用 LongConsumer 调用映射器函数,将替换元素累积到新创建的内部缓冲区中。当映射器函数返回时,它会从内部缓冲区创建一个LongStream。最后,它将这个流返回给 flatMapToLong
      参数:
      mapper - 生成替换元素的 不干扰无国籍的 函数
      返回:
      新流
      自从:
      16
      参见:
    • mapMultiToDouble

      default DoubleStream  mapMultiToDouble(BiConsumer <? super T ,? super DoubleConsumer > mapper)
      返回一个 DoubleStream,由用多个元素(特别是零个或多个元素)替换此流的每个元素的结果组成。通过将提供的映射函数与接受替换元素的consumer参数一起应用于每个元素来执行替换。映射函数零次或多次调用消费者以提供替换元素。

      这是一个 中间操作

      如果 consumer 参数在其映射函数的应用范围之外使用,则结果未定义。

      实现要求:
      默认实现在此流上调用 flatMapToDouble ,传递一个行为如下的函数。首先,它使用 DoubleConsumer 调用映射器函数,将替换元素累积到新创建的内部缓冲区中。当 mapper 函数返回时,它会从内部缓冲区创建一个 DoubleStream。最后,它将这个流返回给 flatMapToDouble
      参数:
      mapper - 生成替换元素的 不干扰无国籍的 函数
      返回:
      新流
      自从:
      16
      参见:
    • distinct

      Stream <T > distinct()
      返回由该流的不同元素(根据 Object.equals(Object) )组成的流。

      对于有序流,不同元素的选择是稳定的(对于重复元素,保留在遇到顺序中首先出现的元素。)对于无序流,不提供稳定性保证。

      这是一个 有状态的中间操作

      API 注意:
      在并行流水线中保持 distinct() 的稳定性相对昂贵(要求该操作作为一个完整的屏障,具有大量的缓冲开销),并且通常不需要稳定性。如果您的情况的语义允许,使用无序流源(例如 generate(Supplier) )或使用 BaseStream.unordered() 删除排序约束可能会导致 distinct() 在并行管道中的执行效率显着提高。如果需要与遇到顺序保持一致,并且在并行管道中使用 distinct() 时性能或内存利用率不佳,则切换到使用 BaseStream.sequential() 的顺序执行可能会提高性能。
      返回:
      新流
    • sorted

      Stream <T > sorted()
      返回一个流,该流由该流的元素组成,并按自然顺序排序。如果此流的元素不是 Comparable ,则在执行终端操作时可能会抛出 java.lang.ClassCastException

      对于有序流,排序是稳定的。对于无序流,不提供稳定性保证。

      这是一个 有状态的中间操作

      返回:
      新流
    • sorted

      Stream <T > sorted(Comparator <? super T > comparator)
      返回由该流的元素组成的流,根据提供的 Comparator 排序。

      对于有序流,排序是稳定的。对于无序流,不提供稳定性保证。

      这是一个 有状态的中间操作

      参数:
      comparator - 一个 不干扰 , 无国籍的 Comparator 用于比较流元素
      返回:
      新流
    • peek

      Stream <T > peek(Consumer <? super T > action)
      返回一个由该流的元素组成的流,当从结果流中消耗元素时,还会对每个元素执行提供的操作。

      这是一个 中间操作

      对于并行流管道,可以在上游操作使元素可用的任何时间和任何线程中调用操作。如果操作修改共享状态,则它负责提供所需的同步。

      API 注意:
      此方法的存在主要是为了支持调试,您希望在元素流过管道中的某个点时查看元素:
      
         Stream.of("one", "two", "three", "four")
           .filter(e -> e.length() > 3)
           .peek(e -> System.out.println("Filtered value: " + e))
           .map(String::toUpperCase)
           .peek(e -> System.out.println("Mapped value: " + e))
           .collect(Collectors.toList());
        

      在流实现能够优化部分或所有元素的生产的情况下(例如使用像 findFirst 这样的短路操作,或者在 count() 中描述的示例中),将不会为这些元素调用操作。

      参数:
      action - 一个 不干扰 在元素从流中消耗时执行的操作
      返回:
      新流
    • limit

      Stream <T > limit(long maxSize)
      返回由该流的元素组成的流,截断后的长度不超过 maxSize

      这是一个 短路状态中间操作

      API 注意:
      虽然 limit() 通常是顺序流管道上的廉价操作,但它在有序并行管道上可能非常昂贵,尤其是对于 maxSize 的大值,因为 limit(n) 不仅限于返回任何 n 元素,而且返回遇到顺序中的 first n 元素。如果您的情况的语义允许,使用无序流源(例如 generate(Supplier) )或使用 BaseStream.unordered() 删除排序约束可能会导致并行管道中的 limit() 显着加速。如果需要与遇到顺序保持一致,并且在并行管道中使用 limit() 时性能或内存利用率不佳,则切换到使用 BaseStream.sequential() 的顺序执行可能会提高性能。
      参数:
      maxSize - 流应限制为的元素数
      返回:
      新流
      抛出:
      IllegalArgumentException - 如果 maxSize 为负
    • skip

      Stream <T > skip(long n)
      在丢弃流的前 n 个元素后,返回由该流的剩余元素组成的流。如果此流包含的元素少于 n 个,则将返回一个空流。

      这是一个 有状态的中间操作

      API 注意:
      虽然 skip() 通常是顺序流管道上的廉价操作,但它在有序并行管道上可能非常昂贵,尤其是对于较大的 n 值,因为 skip(n) 不仅要跳过任何 n 元素,还要跳过遇到顺序中的 first n 元素。如果您的情况的语义允许,使用无序流源(例如 generate(Supplier) )或使用 BaseStream.unordered() 删除排序约束可能会导致并行管道中的 skip() 显着加速。如果需要与遇到顺序保持一致,并且在并行管道中使用 skip() 时性能或内存利用率不佳,则切换到使用 BaseStream.sequential() 的顺序执行可能会提高性能。
      参数:
      n - 要跳过的前导元素数
      返回:
      新流
      抛出:
      IllegalArgumentException - 如果 n 为负
    • takeWhile

      default Stream <T > takeWhile(Predicate <? super T > predicate)
      如果此流是有序的,则返回一个流,该流由从此流中获取的与给定谓词匹配的元素的最长前缀组成。否则,如果此流是无序的,则返回一个流,该流由从此流中获取的与给定谓词匹配的元素的子集组成。

      如果此流是有序的,则最长前缀是此流中与给定谓词匹配的元素的连续序列。序列的第一个元素是该流的第一个元素,紧跟在序列最后一个元素之后的元素不匹配给定的谓词。

      如果这个流是无序的,并且这个流的一些(但不是全部)元素匹配给定的谓词,那么这个操作的行为是不确定的;可以自由获取匹配元素的任何子集(包括空集)。

      独立于此流是有序的还是无序的如果此流的所有元素都匹配给定的谓词,则此操作获取所有元素(结果与输入相同),或者如果流中没有元素匹配给定的谓词则没有元素被采用(结果是一个空流)。

      这是一个 短路状态中间操作

      API 注意:
      虽然 takeWhile() 通常是顺序流管道上的廉价操作,但它在有序并行管道上可能非常昂贵,因为该操作被限制为不仅返回任何有效前缀,而且返回遇到顺序中元素的最长前缀。如果您的情况的语义允许,使用无序流源(例如 generate(Supplier) )或使用 BaseStream.unordered() 删除排序约束可能会导致并行管道中的 takeWhile() 显着加速。如果需要与遇到顺序保持一致,并且在并行管道中使用 takeWhile() 时性能或内存利用率不佳,则切换到使用 BaseStream.sequential() 的顺序执行可能会提高性能。
      实现要求:
      默认实现获取此流的 spliterator ,包装该拆分器以支持此遍历操作的语义,并返回与包装的拆分器关联的新流。返回的流保留了该流的执行特征(即根据 BaseStream.isParallel() 并行或顺序执行),但包装的拆分器可能会选择不支持拆分。当返回的流关闭时,将调用返回流和此流的关闭处理程序。
      参数:
      predicate - 一个 不干扰 , 无国籍的 谓词应用于元素以确定元素的最长前缀。
      返回:
      新流
      自从:
      9
    • dropWhile

      default Stream <T > dropWhile(Predicate <? super T > predicate)
      如果此流是有序的,则返回一个流,该流由删除与给定谓词匹配的元素的最长前缀后的此流的剩余元素组成。否则,如果此流是无序的,则在删除与给定谓词匹配的元素子集后,返回由此流的剩余元素组成的流。

      如果此流是有序的,则最长前缀是此流中与给定谓词匹配的元素的连续序列。序列的第一个元素是该流的第一个元素,紧跟在序列最后一个元素之后的元素不匹配给定的谓词。

      如果这个流是无序的,并且这个流的一些(但不是全部)元素匹配给定的谓词,那么这个操作的行为是不确定的;可以随意删除匹配元素的任何子集(包括空集)。

      独立于此流是有序的还是无序的如果此流的所有元素都匹配给定的谓词,则此操作删除所有元素(结果是一个空流),或者如果流中没有元素匹配给定的谓词则不删除任何元素(结果与输入相同)。

      这是一个 有状态的中间操作

      API 注意:
      虽然 dropWhile() 通常是顺序流管道上的廉价操作,但它在有序并行管道上可能非常昂贵,因为操作被限制为不仅返回任何有效前缀,而且返回遇到顺序中元素的最长前缀。如果您的情况的语义允许,使用无序流源(例如 generate(Supplier) )或使用 BaseStream.unordered() 删除排序约束可能会导致并行管道中的 dropWhile() 显着加速。如果需要与遇到顺序保持一致,并且在并行管道中使用 dropWhile() 时性能或内存利用率不佳,则切换到使用 BaseStream.sequential() 的顺序执行可能会提高性能。
      实现要求:
      默认实现获取此流的 spliterator ,包装该拆分器以支持此遍历操作的语义,并返回与包装的拆分器关联的新流。返回的流保留了该流的执行特征(即根据 BaseStream.isParallel() 并行或顺序执行),但包装的拆分器可能会选择不支持拆分。当返回的流关闭时,将调用返回流和此流的关闭处理程序。
      参数:
      predicate - 一个 不干扰 , 无国籍的 谓词应用于元素以确定元素的最长前缀。
      返回:
      新流
      自从:
      9
    • forEach

      void forEach(Consumer <? super T > action)
      对此流的每个元素执行一个操作。

      这是一个 终端操作

      此操作的行为是明确不确定的。对于并行流管道,此操作确实not保证尊重流的遇到顺序,因为这样做会牺牲并行性的好处。对于任何给定的元素,该操作可以在库选择的任何时间和任何线程中执行。如果操作访问共享状态,它负责提供所需的同步。

      参数:
      action - 对元素执行的 不干扰 操作
    • forEachOrdered

      void forEachOrdered(Consumer <? super T > action)
      如果流具有已定义的遇到顺序,则按照流的遇到顺序为此流的每个元素执行操作。

      这是一个 终端操作

      此操作一次处理一个元素,如果存在则按遇到顺序处理。对一个元素执行操作 发生之前 对后续元素执行操作,但对于任何给定元素,该操作可以在库选择的任何线程中执行。

      参数:
      action - 对元素执行的 不干扰 操作
      参见:
    • toArray

      Object [] toArray()
      返回包含此流的元素的数组。

      这是一个 终端操作

      返回:
      一个数组,其 运行时组件类型Object,包含此流的元素
    • toArray

      <A> A[] toArray(IntFunction <A[]> generator)
      返回一个包含此流元素的数组,使用提供的 generator 函数分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。

      这是一个 终端操作

      API 注意:
      生成器函数接受一个整数,它是所需数组的大小,并生成所需大小的数组。这可以用数组构造函数引用简洁地表达:
      
         Person[] men = people.stream()
                   .filter(p -> p.getGender() == MALE)
                   .toArray(Person[]::new);
        
      类型参数:
      A - 结果数组的组件类型
      参数:
      generator - 生成所需类型和提供长度的新数组的函数
      返回:
      包含此流中元素的数组
      抛出:
      ArrayStoreException - 如果此流的任何元素的运行时类型不可分配给生成数组的 运行时组件类型
    • reduce

      T  reduce(T  identity, BinaryOperator <T > accumulator)
      使用提供的标识值和 联想的 累加函数对此流的元素执行 减少,并返回减少的值。这等同于:
      
         T result = identity;
         for (T element : this stream)
           result = accumulator.apply(result, element)
         return result;
        
      但不限于按顺序执行。

      identity 值必须是累加器函数的标识。这意味着对于所有 taccumulator.apply(identity, t) 等于 taccumulator 函数必须是 联想的 函数。

      这是一个 终端操作

      API 注意:
      Sum、min、max、average 和字符串连接都是归约的特例。对数字流求和可以表示为:
      
         Integer sum = integers.reduce(0, (a, b) -> a+b);
        
      或:
      
         Integer sum = integers.reduce(0, Integer::sum);
        

      虽然与简单地在循环中改变运行总数相比,这似乎是一种执行聚合的更迂回的方式,但缩减操作更优雅地并行化,不需要额外的同步,并且大大降低了数据竞争的风险。

      参数:
      identity - 累积函数的标识值
      accumulator - 一个 联想的不干扰无国籍的 函数用于组合两个值
      返回:
      减少的结果
    • reduce

      Optional <T > reduce(BinaryOperator <T > accumulator)
      使用 联想的 累加函数对此流的元素执行 减少,并返回描述减少值(如果有)的 Optional。这等同于:
      
         boolean foundAny = false;
         T result = null;
         for (T element : this stream) {
           if (!foundAny) {
             foundAny = true;
             result = element;
           }
           else
             result = accumulator.apply(result, element);
         }
         return foundAny ? Optional.of(result) : Optional.empty();
        
      但不限于按顺序执行。

      accumulator 函数必须是 联想的 函数。

      这是一个 终端操作

      参数:
      accumulator - 一个 联想的不干扰无国籍的 函数用于组合两个值
      返回:
      一个 Optional 描述减少的结果
      抛出:
      NullPointerException - 如果归约结果为空
      参见:
    • reduce

      <U> U reduce(U identity, BiFunction <U,? super T ,U> accumulator, BinaryOperator <U> combiner)
      使用提供的标识、累积和组合函数对此流的元素执行 减少。这等效于:
      
         U result = identity;
         for (T element : this stream)
           result = accumulator.apply(result, element)
         return result;
        
      但不限于按顺序执行。

      identity 值必须是组合器函数的标识。这意味着对于所有 ucombiner(identity, u) 等于 u 。此外,combiner函数必须与accumulator函数兼容;对于所有 ut ,必须满足以下条件:

      
         combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
        

      这是一个 终端操作

      API 注意:
      许多使用这种形式的归约可以通过mapreduce操作的显式组合来更简单地表示。 accumulator 函数充当融合的映射器和累加器,有时比单独的映射和缩减更有效,例如当知道先前缩减的值可以避免一些计算时。
      类型参数:
      U - 结果的类型
      参数:
      identity - 组合器函数的标识值
      accumulator - 一个 联想的不干扰无国籍的 函数,用于将附加元素合并到结果中
      combiner - 一个 联想的不干扰无国籍的 函数,用于组合两个值,必须与累加器函数兼容
      返回:
      减少的结果
      参见:
    • collect

      <R> R collect(Supplier <R> supplier, BiConsumer <R,? super T > accumulator, BiConsumer <R,R> combiner)
      对此流的元素执行 可变减少 操作。可变缩减是这样一种缩减,其中缩减值是可变结果容器,例如 ArrayList ,并且通过更新结果状态而不是替换结果来合并元素。这产生的结果等同于:
      
         R result = supplier.get();
         for (T element : this stream)
           accumulator.accept(result, element);
         return result;
        

      reduce(Object, BinaryOperator) 一样,collect 操作可以并行化而不需要额外的同步。

      这是一个 终端操作

      API 注意:
      JDK 中有许多现有的类,它们的签名非常适合与方法引用一起用作 collect() 的参数。例如,以下将把字符串累积到一个 ArrayList 中:
      
         List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add,
                              ArrayList::addAll);
        

      以下将采用字符串流并将它们连接成一个字符串:

      
         String concat = stringStream.collect(StringBuilder::new, StringBuilder::append,
                           StringBuilder::append)
                       .toString();
        
      类型参数:
      R - 可变结果容器的类型
      参数:
      supplier - 一个创建新的可变结果容器的函数。对于并行执行,此函数可能会被调用多次,并且每次都必须返回一个新值。
      accumulator - 一个 联想的不干扰无国籍的 必须将元素折叠到结果容器中的函数。
      combiner - 一个 联想的不干扰无国籍的 函数接受两个部分结果容器并合并它们,它必须与累加器函数兼容。 combiner 函数必须将第二个结果容器中的元素折叠到第一个结果容器中。
      返回:
      减少的结果
    • collect

      <R, A> R collect(Collector <? super T ,A,R> collector)
      使用 Collector 对此流的元素执行 可变减少 操作。 Collector 封装了用作 collect(Supplier, BiConsumer, BiConsumer) 参数的函数,允许重用收集策略和收集操作的组合,例如多级分组或分区。

      如果流是并行的,并且 Collectorconcurrent ,并且流是无序的或者收集器是 unordered ,那么将执行并发缩减(有关并发缩减的详细信息,请参阅 Collector 。)

      这是一个 终端操作

      当并行执行时,可以实例化、填充和合并多个中间结果,以保持可变数据结构的隔离。因此,即使在与非线程安全数据结构(例如 ArrayList )并行执行时,也不需要额外的同步来减少并行。

      API 注意:
      以下将把字符串累积到一个列表中:
      
         List<String> asList = stringStream.collect(Collectors.toList());
        

      以下将按城市对 Person 对象进行分类:

      
         Map<String, List<Person>> peopleByCity
           = personStream.collect(Collectors.groupingBy(Person::getCity));
        

      以下将按州和城市对 Person 对象进行分类,将两个 Collector 级联在一起:

      
         Map<String, Map<String, List<Person>>> peopleByStateAndCity
           = personStream.collect(Collectors.groupingBy(Person::getState,
                                 Collectors.groupingBy(Person::getCity)));
        
      类型参数:
      R - 结果的类型
      A - Collector 的中间累积类型
      参数:
      collector - Collector 描述减少
      返回:
      减少的结果
      参见:
    • toList

      default List <T > toList()
      将此流的元素累积到 List 中。列表中的元素将按照此流的遇到顺序(如果存在的话)。返回的List不可修改;调用任何 mutator 方法将始终导致抛出 UnsupportedOperationException。不保证返回列表的实现类型或可序列化性。

      返回的实例可能是 value-based 。调用者不应假设返回实例的身份。这些实例上的身份敏感操作(引用相等性 (==)、身份哈希码和同步)是不可靠的,应该避免。

      这是一个 终端操作

      API 注意:
      如果需要对返回的对象进行更多控制,请使用 Collectors.toCollection(Supplier)
      实现要求:
      此接口中的实现返回一个由以下内容生成的列表:
      
       Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())))
        
      实现注意事项:
      Stream 的大多数实例将重写此方法并提供与此接口中的实现相比高度优化的实现。
      返回:
      包含流元素的列表
      自从:
      16
    • min

      Optional <T > min(Comparator <? super T > comparator)
      根据提供的 Comparator 返回此流的最小元素。这是 减少 的特例。

      这是一个 终端操作

      参数:
      comparator - a 不干扰 , 无国籍的 Comparator 比较这个流的元素
      返回:
      一个 Optional 描述这个流的最小元素,或者一个空的 Optional 如果流是空的
      抛出:
      NullPointerException - 如果最小元素为空
    • max

      Optional <T > max(Comparator <? super T > comparator)
      根据提供的 Comparator 返回此流的最大元素。这是 减少 的特例。

      这是一个 终端操作

      参数:
      comparator - a 不干扰 , 无国籍的 Comparator 比较这个流的元素
      返回:
      一个 Optional 描述这个流的最大元素,或者一个空的 Optional 如果流是空的
      抛出:
      NullPointerException - 如果最大元素为空
    • count

      long count()
      返回此流中元素的计数。这是 减少 的特例,相当于:
      
         return mapToLong(e -> 1L).sum();
        

      这是一个 终端操作

      API 注意:
      如果实现能够直接从流源计算计数,则它可以选择不执行流管道(顺序或并行)。在这种情况下,不会遍历任何源元素,也不会评估任何中间操作。具有副作用的行为参数可能会受到影响,除了调试等无害情况外,强烈建议不要这样做。例如,考虑以下流:
      
         List<String> l = Arrays.asList("A", "B", "C", "D");
         long count = l.stream().peek(System.out::println).count();
        
      流源 a List 覆盖的元素数量是已知的,中间操作 peek 不会从流中注入或移除元素(如 flatMapfilter 操作)。因此,计数是 List 的大小,并且不需要执行管道,作为副作用,打印出列表元素。
      返回:
      此流中的元素数
    • anyMatch

      boolean anyMatch(Predicate <? super T > predicate)
      返回此流的任何元素是否与提供的谓词匹配。如果不需要确定结果,则可以不对所有元素评估谓词。如果流为空,则返回 false 并且不评估谓词。

      这是一个 短路端子操作

      API 注意:
      此方法评估流元素上谓词的 existential quantification(对于某些 x P(x))。
      参数:
      predicate - 一个 不干扰 , 无国籍的 谓词应用于此流的元素
      返回:
      true 如果流的任何元素与提供的谓词匹配,否则 false
    • allMatch

      boolean allMatch(Predicate <? super T > predicate)
      返回此流的所有元素是否与提供的谓词匹配。如果不需要确定结果,则可以不对所有元素评估谓词。如果流为空,则返回 true 并且不评估谓词。

      这是一个 短路端子操作

      API 注意:
      此方法评估流元素上谓词的universal quantification(对于所有 x P(x))。如果流为空,则称量化为 vacuously satisfied 并且始终为 true(与 P(x) 无关)。
      参数:
      predicate - 一个 不干扰 , 无国籍的 谓词应用于此流的元素
      返回:
      true 如果流的所有元素都匹配提供的谓词或者流为空,否则 false
    • noneMatch

      boolean noneMatch(Predicate <? super T > predicate)
      返回此流中是否没有元素与提供的谓词匹配。如果不需要确定结果,则可以不对所有元素评估谓词。如果流为空,则返回 true 并且不评估谓词。

      这是一个 短路端子操作

      API 注意:
      此方法对流的元素(对于所有 x ~P(x))计算否定谓词的 universal quantification。如果流为空,则称量化是无意义地满足的并且始终为 true ,而不管 P(x)。
      参数:
      predicate - 一个 不干扰 , 无国籍的 谓词应用于此流的元素
      返回:
      true 如果流中没有元素与提供的谓词匹配或流为空,否则 false
    • findFirst

      Optional <T > findFirst()
      返回描述此流的第一个元素的 Optional ,如果流为空,则返回空的 Optional。如果流没有遇到顺序,则可以返回任何元素。

      这是一个 短路端子操作

      返回:
      一个 Optional 描述这个流的第一个元素,或者一个空的 Optional 如果流是空的
      抛出:
      NullPointerException - 如果选择的元素为空
    • findAny

      Optional <T > findAny()
      返回描述流中某些元素的 Optional ,如果流为空,则返回空的 Optional

      这是一个 短路端子操作

      此操作的行为显然是不确定的;可以自由选择流中的任何元素。这是为了在并行操作中实现最大性能;代价是对同一源的多次调用可能不会返回相同的结果。 (如果需要稳定的结果,请改用 findFirst() 。)

      返回:
      一个 Optional 描述这个流的一些元素,或者一个空的 Optional 如果流是空的
      抛出:
      NullPointerException - 如果选择的元素为空
      参见:
    • builder

      static <T> Stream.Builder <T> builder()
      返回 Stream 的构建器。
      类型参数:
      T - 元素类型
      返回:
      流生成器
    • empty

      static <T> Stream <T> empty()
      返回一个空的顺序 Stream
      类型参数:
      T - 流元素的类型
      返回:
      一个空的顺序流
    • of

      static <T> Stream <T> of(T t)
      返回包含单个元素的顺序 Stream
      类型参数:
      T - 流元素的类型
      参数:
      t - 单个元素
      返回:
      单例顺序流
    • ofNullable

      static <T> Stream <T> ofNullable(T t)
      返回包含单个元素的顺序 Stream(如果非空),否则返回空的 Stream
      类型参数:
      T - 流元素的类型
      参数:
      t - 单个元素
      返回:
      如果指定的元素为非空,则为具有单个元素的流,否则为空流
      自从:
      9
    • of

      @SafeVarargs static <T> Stream <T> of(T... values)
      返回其元素为指定值的顺序有序流。
      类型参数:
      T - 流元素的类型
      参数:
      values - 新流的元素
      返回:
      新流
    • iterate

      static <T> Stream <T> iterate(T seed, UnaryOperator <T> f)
      返回由函数 f 迭代应用到初始元素 seed 产生的无限顺序有序 Stream,产生由 seedf(seed)f(f(seed)) 等组成的 Stream

      Stream 中的第一个元素(位置 0 )将是提供的 seed 。对于 n > 0 ,位置 n 的元素将是将函数 f 应用于位置 n - 1 的元素的结果。

      对一个元素应用 f 的动作 发生之前 对后续元素应用 f 的动作。对于任何给定的元素,操作可以在库选择的任何线程中执行。

      类型参数:
      T - 流元素的类型
      参数:
      seed - 初始元素
      f - 应用于前一个元素以生成新元素的函数
      返回:
      一个新的顺序 Stream
    • iterate

      static <T> Stream <T> iterate(T seed, Predicate <? super T> hasNext, UnaryOperator <T> next)
      返回由给定的 next 函数迭代应用到初始元素而产生的顺序有序的 Stream,条件是满足给定的 hasNext 谓词。一旦 hasNext 谓词返回 false,流就会终止。

      Stream.iterate 应该产生与相应的 for 循环产生的相同的元素序列:

      
         for (T index=seed; hasNext.test(index); index = next.apply(index)) {
           ...
         }
        

      如果 hasNext 谓词不保留种子值,则生成的序列可能为空。否则,第一个元素将是提供的 seed 值,下一个元素(如果存在)将是将 next 函数应用于 seed 值的结果,依此类推,直到 hasNext 谓词指示流应该终止。

      hasNext 谓词应用于元素的操作 发生之前next 函数应用于该元素的操作。对一个元素应用next函数的动作发生之前对后续元素应用 hasNext 谓词的操作。对于任何给定的元素,可以在库选择的任何线程中执行操作。

      类型参数:
      T - 流元素的类型
      参数:
      seed - 初始元素
      hasNext - 应用于元素以确定流何时必须终止的谓词。
      next - 应用于前一个元素以生成新元素的函数
      返回:
      一个新的顺序 Stream
      自从:
      9
    • generate

      static <T> Stream <T> generate(Supplier <? extends T> s)
      返回无限顺序无序流,其中每个元素都由提供的 Supplier 生成。这适用于生成恒定流、随机元素流等。
      类型参数:
      T - 流元素的类型
      参数:
      s - 生成元素的 Supplier
      返回:
      一个新的无限顺序无序Stream
    • concat

      static <T> Stream <T> concat(Stream <? extends T> a, Stream <? extends T> b)
      创建一个惰性串联流,其元素是第一个流的所有元素,后跟第二个流的所有元素。如果两个输入流都是有序的,则结果流是有序的,如果其中一个输入流是并行的,则结果流是并行的。当结果流关闭时,将调用两个输入流的关闭处理程序。

      此方法对两个输入流进行操作并将每个流绑定到其源。因此,对输入流源的后续修改可能不会反映在级联流结果中。

      API 注意:
      为了保留优化机会,此方法将每个流绑定到其源并仅接受两个流作为参数。例如,如果知道每个输入流源的确切大小,则可以计算连接流源的确切大小。要在不绑定或不嵌套调用此方法的情况下连接更多流,请尝试使用标识函数创建流流和平面映射流,例如:
      
         Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s);
        
      实现注意事项:
      从重复串联构造流时要小心。访问深度串联流的元素可能会导致深度调用链,甚至 StackOverflowError

      返回流的顺序/并行执行模式的后续更改不能保证传播到输入流。

      类型参数:
      T - 流元素的类型
      参数:
      a - 第一个流
      b - 第二个流
      返回:
      两个输入流的连接