-
- 参数类型
-
T- 流元素的类型
- All Superinterfaces:
-
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();widgets是Collection<Widget>。 我们通过Collection.stream()创建一个Widget对象流,过滤它以生成仅包含红色小部件的流,然后将其转换为表示每个红色小部件权重的int值的流。 然后将该流相加以产生总重量。除了
Stream,这是对象引用的流,存在原语特为IntStream,LongStream,和DoubleStream,所有这些都称为“流”和符合此处描述的特征和限制。为了执行计算,将流operations组合成流管道 。 流管道由源(可能是数组,集合,生成器函数,I / O通道等),零个或多个中间操作 (将流转换为另一个流,如
filter(Predicate))组成,以及终端操作 (产生结果或副作用,例如count()或forEach(Consumer))。 溪流很懒; 仅在启动终端操作时才执行对源数据的计算,并且仅在需要时消耗源元素。允许流实现在优化结果的计算方面具有显着的自由度。 例如,流实现可以自由地从流管道中删除操作(或整个阶段) - 因此可以省略对行为参数的调用 - 如果它可以证明它不会影响计算结果。 这意味着除非另有说明(例如通过终端操作
forEach和forEachOrdered),否则行为参数的副作用可能并不总是被执行且不应该被依赖。 (有关此类优化的具体示例,请参阅count()操作中记录的API说明。有关更多详细信息,请参阅流包文档的side-effects部分。)收藏和流虽然有一些肤浅的相似之处,但却有不同的目标。 馆藏主要关注其元素的有效管理和访问。 相比之下,流不提供直接访问或操纵其元素的手段,而是涉及声明性地描述它们的源以及将在该源上聚合执行的计算操作。 但是,如果提供的流操作不提供所需的功能,则可以使用
BaseStream.iterator()和BaseStream.spliterator()操作来执行受控遍历。流管道(如上面的“小部件”示例)可以视为流源上的查询 。 除非源是为并发修改而明确设计的(例如
ConcurrentHashMap),否则在查询流源时可能会导致不可预测或错误的行为。大多数流操作接受描述用户指定行为的参数,例如上面示例中传递给
mapToInt的lambda表达式w -> w.getWeight()。 为了保持正确的行为,这些行为参数 :- 必须是non-interfering (他们不修改流源); 和
- 在大多数情况下,必须为stateless (其结果不应取决于在执行流管道期间可能更改的任何状态)。
这些参数始终是functional interface的实例,例如
Function,并且通常是lambda表达式或方法引用。 除非另有说明,否则这些参数必须为非null 。应该只对一个流进行操作(调用中间或终端流操作)。 例如,这排除了“分叉”流,其中相同的源提供两个或更多个管道,或者同一个流的多个遍历。 如果流实现检测到正在重用流,则可能会抛出
IllegalStateException。 但是,由于某些流操作可能返回其接收器而不是新的流对象,因此可能无法在所有情况下检测重用。Streams具有
BaseStream.close()方法并实现AutoCloseable。 在关闭后在流上操作将抛出IllegalStateException。 大多数流实例实际上不需要在使用后关闭,因为它们由集合,数组或生成函数支持,不需要特殊的资源管理。 通常,只有源为IO通道的流(例如Files.lines(Path)返回的流 )才需要关闭。 如果流确实需要关闭,则必须在try-with-resources语句或类似控制结构中将其作为资源打开,以确保在操作完成后立即关闭它。流管道可以按顺序执行,也可以在parallel中执行。 此执行模式是流的属性。 通过初始选择的顺序或并行执行来创建流。 (例如,
Collection.stream()创建顺序流,Collection.parallelStream()创建并行流。)执行模式的选择可以通过BaseStream.sequential()或BaseStream.parallel()方法进行修改,并且可以使用BaseStream.isParallel()方法进行查询。- 从以下版本开始:
- 1.8
- 另请参见:
-
IntStream,LongStream,DoubleStream, java.util.stream
-
-
嵌套类汇总
嵌套类 变量和类型 接口 描述 static interfaceStream.Builder<T>适用于Stream可变构建器。
-
方法摘要
所有方法 静态方法 实例方法 抽象方法 Default Methods 变量和类型 方法 描述 booleanallMatch(Predicate<? super T> predicate)返回此流的所有元素是否与提供的谓词匹配。booleananyMatch(Predicate<? super T> predicate)返回此流的任何元素是否与提供的谓词匹配。static <T> Stream.Builder<T>builder()返回Stream的构建器。<R> Rcollect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)对此流的元素执行 mutable reduction操作。<R,A>
Rcollect(Collector<? super T,A,R> collector)使用Collector对此流的元素执行 mutable reduction操作。static <T> Stream<T>concat(Stream<? extends T> a, Stream<? extends T> b)创建一个延迟连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。longcount()返回此流中元素的数量。Stream<T>distinct()返回由此流的不同元素(根据Object.equals(Object))组成的流。default Stream<T>dropWhile(Predicate<? super T> predicate)如果对此流进行排序,则返回在删除与给定谓词匹配的元素的最长前缀之后由该流的其余元素组成的流。static <T> Stream<T>empty()返回空序列Stream。Stream<T>filter(Predicate<? super T> predicate)返回由与此给定谓词匹配的此流的元素组成的流。Optional<T>findAny()返回Optional描述流的一些元件,或一个空Optional如果流是空的。Optional<T>findFirst()返回Optional描述此流的第一个元素,或空Optional如果流是空的。<R> Stream<R>flatMap(Function<? super T,? extends Stream<? extends R>> mapper)返回一个流,该流包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。DoubleStreamflatMapToDouble(Function<? super T,? extends DoubleStream> mapper)返回DoubleStream其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。IntStreamflatMapToInt(Function<? super T,? extends IntStream> mapper)返回IntStream其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。LongStreamflatMapToLong(Function<? super T,? extends LongStream> mapper)返回LongStream其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。voidforEach(Consumer<? super T> action)对此流的每个元素执行操作。voidforEachOrdered(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生成的顺序有序Stream,条件是满足给定的hasNext谓词。static <T> Stream<T>iterate(T seed, UnaryOperator<T> f)返回有序无限连续Stream由函数的迭代应用产生f到初始元素seed,产生Stream组成的seed,f(seed),f(f(seed))等Stream<T>limit(long maxSize)返回由此流的元素组成的流,截断长度不超过maxSize。<R> Stream<R>map(Function<? super T,? extends R> mapper)返回一个流,该流包含将给定函数应用于此流的元素的结果。DoubleStreammapToDouble(ToDoubleFunction<? super T> mapper)返回DoubleStream其中包含将给定函数应用于此流的元素的结果。IntStreammapToInt(ToIntFunction<? super T> mapper)返回IntStream其中包含将给定函数应用于此流的元素的结果。LongStreammapToLong(ToLongFunction<? super T> mapper)返回LongStream其中包含将给定函数应用于此流的元素的结果。Optional<T>max(Comparator<? super T> comparator)根据提供的Comparator返回此流的最大元素。Optional<T>min(Comparator<? super T> comparator)根据提供的Comparator返回此流的最小元素。booleannoneMatch(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(如果为非null),否则返回空Stream。Stream<T>peek(Consumer<? super T> action)返回由此流的元素组成的流,另外在每个元素上执行提供的操作,因为元素是从结果流中消耗的。Optional<T>reduce(BinaryOperator<T> accumulator)Treduce(T identity, BinaryOperator<T> accumulator)使用提供的标识值和 associative累积函数对此流的元素执行 reduction ,并返回减小的值。<U> Ureduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)使用提供的标识,累积和组合功能对此流的元素执行 reduction 。Stream<T>skip(long n)在丢弃流的第一个n元素后,返回由此流的其余元素组成的流。Stream<T>sorted()返回由此流的元素组成的流,按照自然顺序排序。Stream<T>sorted(Comparator<? super T> comparator)返回由此流的元素组成的流,根据提供的Comparator进行排序。default Stream<T>takeWhile(Predicate<? super T> predicate)如果对此流进行排序,则返回一个流,该流包含从此流中获取的与给定谓词匹配的最长元素前缀。Object[]toArray()返回包含此流的元素的数组。<A> A[]toArray(IntFunction<A[]> generator)返回包含此流元素的数组,使用提供的generator函数分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。-
声明方法的接口 java.util.stream.BaseStream
close, isParallel, iterator, onClose, parallel, sequential, spliterator, unordered
-
-
-
-
方法详细信息
-
filter
Stream<T> filter(Predicate<? super T> predicate)
返回由与此给定谓词匹配的此流的元素组成的流。这是一个intermediate operation 。
- 参数
-
predicate-一个 non-interfering , stateless谓词应用到每个元素,以确定是否它应包含 - 结果
- 新流
-
map
<R> Stream<R> map(Function<? super T,? extends R> mapper)
返回一个流,该流包含将给定函数应用于此流的元素的结果。这是一个intermediate operation 。
- 参数类型
-
R- 新流的元素类型 - 参数
-
mapper-一个 non-interfering , stateless函数应用到每个元件 - 结果
- 新流
-
mapToInt
IntStream mapToInt(ToIntFunction<? super T> mapper)
返回IntStream其中包含将给定函数应用于此流的元素的结果。这是一个intermediate operation 。
- 参数
-
mapper-一个 non-interfering , stateless函数应用到每个元件 - 结果
- 新流
-
mapToLong
LongStream mapToLong(ToLongFunction<? super T> mapper)
返回LongStream其中包含将给定函数应用于此流的元素的结果。- 参数
-
mapper-一个 non-interfering , stateless函数应用到每个元件 - 结果
- 新流
-
mapToDouble
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)
返回DoubleStream其中包含将给定函数应用于此流的元素的结果。这是一个intermediate operation 。
- 参数
-
mapper-一个 non-interfering , stateless函数应用到每个元件 - 结果
- 新流
-
flatMap
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
返回一个流,该流包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。 将其内容放入此流后,每个映射的流都为closed。 (如果映射的流是null,则使用空流。)这是一个intermediate operation 。
- API Note:
-
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(" +")));flatMap的mapper函数使用简单的正则表达式将一条线拆分为一个单词数组,然后从该数组创建一个单词流。 - 参数类型
-
R- 新流的元素类型 - 参数
-
mapper-一个 non-interfering , stateless功能应用到其产生新的值的流的每个元素 - 结果
- 新流
-
flatMapToInt
IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper)
返回IntStream其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。 将其内容放入此流后,每个映射的流都为closed。 (如果映射的流是null,则使用空流。)这是一个intermediate operation 。
- 参数
-
mapper-一个 non-interfering , stateless功能应用到其产生新的值的流的每个元素 - 结果
- 新流
- 另请参见:
-
flatMap(Function)
-
flatMapToLong
LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper)
返回LongStream其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。 将其内容放入此流后,每个映射的流都为closed。 (如果映射的流是null,则使用空流。)这是一个intermediate operation 。
- 参数
-
mapper-一个 non-interfering , stateless功能应用到其产生新的值的流的每个元素 - 结果
- 新流
- 另请参见:
-
flatMap(Function)
-
flatMapToDouble
DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
返回DoubleStream其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。 在将其内容放入此流之后,每个映射的流都是closed。 (如果映射的流是null,则使用空流。)这是一个intermediate operation 。
- 参数
-
mapper-一个 non-interfering , stateless功能应用到其产生新的值的流的每个元素 - 结果
- 新流
- 另请参见:
-
flatMap(Function)
-
distinct
Stream<T> distinct()
返回由此流的不同元素(根据Object.equals(Object))组成的流。对于有序流,不同元素的选择是稳定的(对于重复元素,保留在遇到顺序中首先出现的元素。)对于无序流,不进行稳定性保证。
- API Note:
-
在并行管道中保持
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-一个 non-interfering , statelessComparator被用于比较流元素 - 结果
- 新流
-
peek
Stream<T> peek(Consumer<? super T> action)
返回由此流的元素组成的流,另外在每个元素上执行提供的操作,因为元素是从结果流中消耗的。这是一个intermediate operation 。
对于并行流管道,可以在任何时间以及上游操作使元素可用的任何线程中调用该动作。 如果操作修改共享状态,则它负责提供所需的同步。
- API Note:
-
此方法主要用于支持调试,您希望在元素流经管道中的某个点时查看这些元素:
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- 对从流中使用的元素执行的操作 non-interfering - 结果
- 新流
-
limit
Stream<T> limit(long maxSize)
返回由此流的元素组成的流,截断长度不超过maxSize。- API Note:
-
虽然
limit()通常是顺序流管道上的廉价操作,但在有序并行管道上可能相当昂贵,特别是对于maxSize大值,因为limit(n)要返回任何n个元素,而且还要返回遭遇顺序中的前n个元素。 使用无序流源(例如generate(Supplier))或去除所述排序约束与BaseStream.unordered()可能导致显著加速比limit()在并行管线,如果情况许可的语义。 如果具有遭遇顺序的一致性是必须的,并且遇到性能或存储器利用率差与limit()在并行管线,在切换到的顺序执行与BaseStream.sequential()可以提高性能。 - 参数
-
maxSize- 应限制流的元素数 - 结果
- 新流
- 异常
-
IllegalArgumentException- 如果maxSize为负数
-
skip
Stream<T> skip(long n)
- API Note:
-
虽然
skip()通常是顺序流管道上的廉价操作,但在有序并行管道上可能相当昂贵,特别是对于大值n,因为skip(n)被限制为不仅跳过任何n个元素,而是跳过遭遇顺序中的前n个元素。 使用无序流源(例如generate(Supplier))或去除所述排序约束与BaseStream.unordered()可能导致显著加速比skip()在并行管线,如果情况许可的语义。 如果具有遭遇顺序的一致性是必须的,并且遇到性能或存储器利用率差与skip()在并行管线,在切换到的顺序执行与BaseStream.sequential()可以提高性能。 - 参数
-
n- 要跳过的主要元素的数量 - 结果
- 新流
- 异常
-
IllegalArgumentException- 如果n为负数
-
takeWhile
default Stream<T> takeWhile(Predicate<? super T> predicate)
如果对此流进行排序,则返回一个流,该流包含从此流中获取的与给定谓词匹配的最长元素前缀。 否则,如果此流是无序的,则返回由从此流中获取的与给定谓词匹配的元素子集组成的流。如果对此流进行排序,则最长前缀是与该给定谓词匹配的该流的连续元素序列。 序列的第一个元素是此流的第一个元素,紧跟在序列的最后一个元素之后的元素与给定的谓词不匹配。
如果此流是无序的,并且此流的某些(但不是所有)元素与给定谓词匹配,则此操作的行为是不确定的; 它可以自由地获取匹配元素的任何子集(包括空集)。
如果此流的所有元素与给定谓词匹配,则此流是有序还是无序,无论此操作是否接受所有元素(结果与输入相同),或者如果流的任何元素都不匹配给定谓词,则没有元素被采取(结果是一个空流)。
- API Note:
-
虽然
takeWhile()通常是顺序流管道上的廉价操作,但在有序并行管道上它可能非常昂贵,因为操作被约束为不仅返回任何有效前缀,而是返回遭遇顺序中元素的最长前缀。 使用无序流源(例如generate(Supplier))或去除所述排序约束与BaseStream.unordered()可能导致显著加速比takeWhile()在并行管线,如果情况许可的语义。 如果具有遭遇顺序的一致性是必须的,并且遇到性能或存储器利用率差与takeWhile()在并行管线,在切换到的顺序执行与BaseStream.sequential()可以提高性能。 - 实现要求:
-
默认实现获取此流的
spliterator,包装该spliterator以便在遍历时支持此操作的语义,并返回与包装的spliterator关联的新流。 返回的流保留该流的执行特性(即根据BaseStream.isParallel()的并行或顺序执行),但是包装的分裂器可以选择不支持分割。 返回的流关闭后,将调用返回的流和此流的关闭处理程序。 - 参数
-
predicate-一个 non-interfering , stateless谓词适用于元素,以确定元素的最长前缀。 - 结果
- 新流
- 从以下版本开始:
- 9
-
dropWhile
default Stream<T> dropWhile(Predicate<? super T> predicate)
如果对此流进行排序,则返回在删除与给定谓词匹配的元素的最长前缀之后由该流的其余元素组成的流。 否则,如果此流是无序的,则返回在删除与给定谓词匹配的元素子集之后由该流的其余元素组成的流。如果对此流进行排序,则最长前缀是与该给定谓词匹配的该流的连续元素序列。 序列的第一个元素是此流的第一个元素,紧跟在序列的最后一个元素之后的元素与给定的谓词不匹配。
如果此流是无序的,并且此流的某些(但不是所有)元素与给定谓词匹配,则此操作的行为是不确定的; 它可以自由地删除匹配元素的任何子集(包括空集)。
如果此流的所有元素与给定谓词匹配,则该流是有序还是无序,无论该操作是否丢弃所有元素(结果是空流),或者如果流的任何元素都不匹配给定谓词,则不会丢弃任何元素(结果与输入相同)。
- API Note:
-
虽然
dropWhile()通常是对顺序流管道的廉价操作,但在有序并行管道上它可能非常昂贵,因为操作被约束为不仅返回任何有效前缀,而是返回遭遇顺序中元素的最长前缀。 使用无序流源(例如generate(Supplier))或去除所述排序约束与BaseStream.unordered()可能导致显著加速比dropWhile()在并行管线,如果情况许可的语义。 如果具有遭遇顺序的一致性是必须的,并且遇到性能或存储器利用率差与dropWhile()在并行管线,在切换到的顺序执行与BaseStream.sequential()可以提高性能。 - 实现要求:
-
默认实现获取此流的
spliterator,包装该spliterator以便在遍历时支持此操作的语义,并返回与包装的spliterator关联的新流。 返回的流保留此流的执行特征(即根据BaseStream.isParallel()的并行或顺序执行),但是包装的分裂器可以选择不支持分割。 返回的流关闭后,将调用返回的流和此流的关闭处理程序。 - 参数
-
predicate-一个 non-interfering , stateless谓词适用于元素,以确定元素的最长前缀。 - 结果
- 新流
- 从以下版本开始:
- 9
-
forEach
void forEach(Consumer<? super T> action)
对此流的每个元素执行操作。此操作的行为明确是不确定的。 对于并行流管道,此操作并不保证尊重流的相遇顺序,因为这样做会牺牲并行的利益。 对于任何给定元素,可以在任何时间以及库选择的任何线程中执行该动作。 如果操作访问共享状态,则它负责提供所需的同步。
- 参数
-
action- 要对元素执行的 non-interfering操作
-
forEachOrdered
void forEachOrdered(Consumer<? super T> action)
如果流具有已定义的遭遇顺序,则按流的遭遇顺序对此流的每个元素执行操作。这是一个terminal operation 。
此操作一次一个地处理元素,如果存在则以遭遇顺序处理。 对一个元素执行操作happens-before为后续元素执行操作,但对于任何给定元素,可以在库选择的任何线程中执行操作。
- 参数
-
action- 要对元素执行的 non-interfering操作 - 另请参见:
-
forEach(Consumer)
-
toArray
Object[] toArray()
返回包含此流的元素的数组。这是一个terminal operation 。
- 结果
-
一个数组,其
runtime component type是
Object,包含此流的元素
-
toArray
<A> A[] toArray(IntFunction<A[]> generator)
返回包含此流元素的数组,使用提供的generator函数分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。这是一个terminal operation 。
- API Note:
-
生成器函数采用整数,该整数是所需数组的大小,并生成所需大小的数组。
这可以用数组构造函数引用简洁地表达:
Person[] men = people.stream() .filter(p -> p.getGender() == MALE) .toArray(Person[]::new); - 参数类型
-
A- 结果数组的组件类型 - 参数
-
generator- 生成所需类型和提供长度的新数组的函数 - 结果
- 包含此流中元素的数组
- 异常
-
ArrayStoreException- 如果此流的任何元素的运行时类型不能分配给生成的数组的 runtime component type
-
reduce
T reduce(T identity, BinaryOperator<T> accumulator)
使用提供的标识值和associative累积函数对此流的元素执行reduction ,并返回减少的值。 这相当于:但不限于按顺序执行。T result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;identity值必须是累加器函数的标识。 这意味着,对于所有t,accumulator.apply(identity, t)等于t。accumulator函数必须是associative函数。这是一个terminal operation 。
- API Note:
-
Sum,min,max,average和string concatenation都是减少的特例。
汇总数字流可以表示为:
要么:Integer sum = integers.reduce(0, (a, b) -> a+b);Integer sum = integers.reduce(0, Integer::sum);虽然与简单地在循环中改变运行总计相比,这似乎是更加迂回的执行聚合的方式,但是还原操作可以更优雅地并行化,而无需额外的同步并且大大降低了数据竞争的风险。
- 参数
-
identity- 累积函数的标识值 -
accumulator-一个 associative , non-interfering , stateless功能组合两个值 - 结果
- 减少的结果
-
reduce
Optional<T> reduce(BinaryOperator<T> accumulator)
使用associative累积功能对此流的元素执行reduction ,并返回描述减少值的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功能必须是associative功能。这是一个terminal operation 。
- 参数
-
accumulator-一个 associative , non-interfering , stateless功能组合两个值 - 结果
-
Optional描述了减少的结果 - 异常
-
NullPointerException- 如果减少的结果为空 - 另请参见:
-
reduce(Object, BinaryOperator),min(Comparator),max(Comparator)
-
reduce
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)使用提供的标识,累积和组合功能对此流的元素执行reduction 。 这相当于:但不限于按顺序执行。U result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;identity值必须是组合器函数的标识。 这意味着,对于所有u,combiner(identity, u)等于u。 此外,combiner功能必须与accumulator功能兼容; 对于所有u和t,必须满足以下条件:combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)这是一个terminal operation 。
- API Note:
-
使用此形式的许多减少可以通过
map和reduce操作的明确组合更简单地表示。accumulator函数充当融合映射器和累加器,有时比单独的映射和缩减更有效,例如当知道先前减小的值允许您避免某些计算时。 - 参数类型
-
U- 结果的类型 - 参数
-
identity- 组合器函数的标识值 -
accumulator-一个 associative , non-interfering , stateless功能用于将一个额外的元件到结果 -
combiner-一个 associative , non-interfering , stateless功能用于组合两个值,它必须与蓄能器功能兼容 - 结果
- 减少的结果
- 另请参见:
-
reduce(BinaryOperator),reduce(Object, BinaryOperator)
-
collect
<R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
对此流的元素执行mutable reduction操作。 可变减少是其中减少的值是可变结果容器(例如ArrayList,并且通过更新结果的状态而不是通过替换结果来合并元素。 这产生的结果相当于:R result = supplier.get(); for (T element : this stream) accumulator.accept(result, element); return result;与
reduce(Object, BinaryOperator)类似 ,可以并行化collect操作,而无需额外的同步。这是一个terminal operation 。
- API Note:
-
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-一个 associative , non-interfering , stateless功能必须的元件折叠成的结果容器。 -
combiner-一个associative , non-interfering , stateless函数接受两个部分结果的容器和将它们合并,这必须与累加器功能兼容。 组合器函数必须将元素从第二个结果容器折叠到第一个结果容器中。 - 结果
- 减少的结果
-
collect
<R,A> R collect(Collector<? super T,A,R> collector)
使用Collector对此流的元素执行mutable reduction操作。Collector封装了用作collect(Supplier, BiConsumer, BiConsumer)参数的函数,允许重用收集策略和收集操作的组合,例如多级分组或分区。如果流是并行的,并且
Collector是concurrent,并且流是无序的或收集器是unordered,则将执行并发减少(有关并发减少的详细信息,请参阅Collector)。这是一个terminal operation 。
当并行执行时,可以实例化,填充和合并多个中间结果,以便保持可变数据结构的隔离。 因此,即使与非线程安全数据结构并行执行(例如
ArrayList),并行还原也不需要额外的同步。- API Note:
-
以下内容将字符串累积到ArrayList中:
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 - 结果
- 减少的结果
- 另请参见:
-
collect(Supplier, BiConsumer, BiConsumer),Collectors
-
min
Optional<T> min(Comparator<? super T> comparator)
- 参数
-
comparator-一个 non-interfering , statelessComparator比较该流的元素 - 结果
-
一个
Optional描述该流的一个空的最小元件,或Optional如果流是空 - 异常
-
NullPointerException- 如果最小元素为null
-
max
Optional<T> max(Comparator<? super T> comparator)
- 参数
-
comparator-一个 non-interfering , statelessComparator比较该流的元素 - 结果
-
一个
Optional描述此流的最大元素,或空Optional如果流是空 - 异常
-
NullPointerException- 如果最大元素为null
-
count
long count()
- API Note:
-
如果实现可以直接从流源计算计数,则实现可以选择不执行流管道(顺序地或并行地)。
在这种情况下,不会遍历任何源元素,也不会评估中间操作。
除了诸如调试之类的无害情况之外,强烈不鼓励具有副作用的行为参数可能会受到影响。
例如,请考虑以下流:
流源(List<String> l = Arrays.asList("A", "B", "C", "D"); long count = l.stream().peek(System.out::println).count();List所涵盖的元素数量是已知的,并且中间操作peek不会从流中注入或移除元素(flatMap或filter操作可能是这种情况)。 因此,计数是List的大小,并且不需要执行管道,并且作为副作用,打印出列表元素。 - 结果
- 此流中的元素数
-
anyMatch
boolean anyMatch(Predicate<? super T> predicate)
返回此流的任何元素是否与提供的谓词匹配。 如果不是确定结果所必需的,则不能评估所有元素的谓词。 如果流为空,则返回false,并且不评估谓词。- API Note:
- 此方法评估谓词对流的元素的 存在量化 (对于某些x P(x))。
- 参数
-
predicate-一个 non-interfering , stateless谓词适用于该流的元素 - 结果
-
true如果流的任何元素与提供的谓词匹配,否则为false
-
allMatch
boolean allMatch(Predicate<? super T> predicate)
返回此流的所有元素是否与提供的谓词匹配。 如果不是确定结果所必需的,则不能评估所有元素的谓词。 如果流为空,则返回true,并且不评估谓词。- API Note:
-
此方法评估谓词对流的元素的通用量化 (对于所有x P(x))。
如果流是空的,则称量化是空心满足的并且始终为
true(不管P(x))。 - 参数
-
predicate-一个 non-interfering , stateless谓词适用于该流的元素 - 结果
-
true如果流的所有元素都与提供的谓词匹配或流为空,否则为false
-
noneMatch
boolean noneMatch(Predicate<? super T> predicate)
返回此流的元素是否与提供的谓词匹配。 如果不是确定结果所必需的,则不能评估所有元素的谓词。 如果流为空,则返回true,并且不评估谓词。- API Note:
-
该方法评估否定谓词对流的元素的通用量化 (对于所有x~P(x))。
如果流是空的,则称量化是空心满足的,并且总是
true,而不管P(x)。 - 参数
-
predicate-一个 non-interfering , stateless谓词适用于该流的元素 - 结果
-
true如果流中没有元素与提供的谓词匹配或者流为空,否则为false
-
findFirst
Optional<T> findFirst()
返回Optional描述此流的第一个元素,或空Optional如果流是空的。 如果流没有遭遇顺序,则可以返回任何元素。- 结果
-
一个
Optional描述此流的第一个元素,或空Optional如果流是空 - 异常
-
NullPointerException- 如果选择的元素为null
-
findAny
Optional<T> findAny()
返回Optional描述流的一些元件,或一个空Optional如果流是空的。这是一个short-circuiting terminal operation 。
此操作的行为明确是不确定的; 可以自由选择流中的任何元素。 这是为了在并行操作中实现最大性能; 成本是同一源上的多次调用可能不会返回相同的结果。 (如果需要稳定的结果,请改用
findFirst()。 )- 结果
-
一个
Optional描述该流的一些元件,或一个空Optional如果流是空 - 异常
-
NullPointerException- 如果选择的元素为null - 另请参见:
-
findFirst()
-
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(如果为非null),否则返回空Stream。- 参数类型
-
T- 流元素的类型 - 参数
-
t- 单个元素 - 结果
- 如果指定的元素为非null,则为具有单个元素的流,否则为空流
- 从以下版本开始:
- 9
-
of
@SafeVarargs static <T> Stream<T> of(T... values)
返回其元素为指定值的顺序有序流。- 参数类型
-
T- 流元素的类型 - 参数
-
values- 新流的元素 - 结果
- 新流
-
iterate
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
返回有序无限连续Stream由函数的迭代应用产生f到初始元素seed,产生Stream组成的seed,f(seed),f(f(seed))等第一元件(位置
0在)Stream将是提供seed。 对于n > 0,位置n处的元素将是将函数f应用于位置n - 1处的元素的n - 1。施加的作用
f为一个元件happens-before施加的作用f用于随后的元件。 对于任何给定元素,可以在库选择的任何线程中执行操作。- 参数类型
-
T- 流元素的类型 - 参数
-
seed- 初始元素 -
f- 要应用于上一个元素以生成新元素的函数 - 结果
-
一个新的顺序
Stream
-
iterate
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
返回通过将给定的next函数迭代应用于初始元素Stream生成的顺序有序Stream,条件是满足给定的hasNext谓词。 一旦hasNext谓词返回false,流就会终止。Stream.iterate应该生成与相应的for循环生成的元素序列相同的元素:for (T index=seed; hasNext.test(index); index = next.apply(index)) { ... }如果
hasNext谓词不保留种子值,则结果序列可能为空。 否则,第一个元素将是提供的seed值,下一个元素(如果存在)将是将next函数应用于seed值的结果,依此类推,直到hasNext谓词指示流应该终止。将
hasNext谓词应用于元素happens-before将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 Note:
-
为了保留优化机会,此方法将每个流绑定到其源,并仅接受两个流作为参数。
例如,如果已知每个输入流源的确切大小,则可以计算级联流源的确切大小。
要在不绑定的情况下连接更多流,或者不对此方法进行嵌套调用,请尝试使用标识函数创建流和平面映射流,例如:
Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s); - Implementation Note:
-
从重复串联构造流时要小心。
访问深度连接的流的元素可能会导致深度调用链,甚至是
StackOverflowError。对返回流的顺序/并行执行模式的后续更改不保证传播到输入流。
- 参数类型
-
T- 流元素的类型 - 参数
-
a- 第一个流 -
b- 第二个流 - 结果
- 两个输入流的串联
-
-