java8新特新:接口流-Stream()接口和所有方法(map,foreach,filter,count,distinct,limit,collect,skip,sorted)
Steam<T>
接口流
- 类型参数:
-
T
- 流元素的类型
- 所有超级接口:
- AutoCloseable,BaseStream <T,Stream <T >>
公共接口Stream <T> 扩展BaseStream <T,Stream <T >>
支持顺序和并行聚合操作的一系列元素。以下示例说明使用Stream
and 的聚合操作IntStream
:int sum = widgets.stream().filter(w -> w.getColor() == RED).mapToInt(w -> w.getWeight()).sum();
在这个例子中,
widgets
是一个Collection<Widget>
。我们通过创建一个Widget
对象流Collection.stream()
,对其进行过滤以产生只包含红色小部件的流,然后将其转换为int
代表每个红色小部件权重的值流。然后将这个流加起来产生总重量。除了
Stream
,这是对象引用的流,存在用于原始特IntStream
,LongStream
以及DoubleStream
,所有这些都称为“流”和符合此处描述的特征和限制。为了执行计算,流 操作被组成 流管道。一个流管道由一个源(可能是一个数组,一个集合,一个生成器函数,一个I / O通道等),零个或多个中间操作(将流转换成另一个流等
filter(Predicate)
) 终端操作(产生结果或副作用,如count()
orforEach(Consumer)
)。流是懒惰的; 源数据的计算仅在终端操作启动时执行,而源元素仅在需要时消耗。收藏和流媒体虽然有一些肤浅的相似之处,却有着不同的目标。收藏主要关心对元素的有效管理和访问。相比之下,流不提供直接访问或操作元素的手段,而是关注于声明性地描述它们的来源以及将在该来源上进行的计算操作。然而,如果提供的流的操作不提供所期望的功能性,
BaseStream.iterator()
并且BaseStream.spliterator()
操作可用于执行受控的遍历。流管道,就像上面的“小部件”示例一样,可以被视为流源上的查询。除非源代码被明确设计用于并发修改(如a
ConcurrentHashMap
),否则在查询流源时修改流源可能会导致不可预知或错误的行为。大多数流操作接受描述用户指定行为的参数,例如上例中
w -> w.getWeight()
传递给 的lambda表达式mapToInt
。为了保持正确的行为,这些行为参数:- 必须是无干扰的 (他们不会修改流源); 和
- 在大多数情况下,它们必须是无状态的 (它们的结果不应该依赖于在流管道执行期间可能会改变的任何状态)。
这样的参数总是一个实例 功能接口如
Function
,也常常lambda表达式或方法的引用。除非另有规定,否则这些参数必须 是非空的。应该只对一个数据流进行操作(调用中间或终端流操作)一次。这排除了例如“分叉”流,其中相同的源馈送两个或更多个管线,或者多个遍历相同的流。如果流
IllegalStateException
检测到流正在被重用,可能会抛出流。然而,由于一些流操作可能返回它们的接收者而不是新的流对象,所以在所有情况下可能无法检测到重用。流有一个
BaseStream.close()
方法和实现AutoCloseable
,但几乎所有的流实例实际上并不需要在使用后关闭。一般来说,只有来源是IO通道的流(例如返回的流Files.lines(Path, Charset)
)需要关闭。大多数流都由集合,数组或者生成函数来支持,而不需要特殊的资源管理。(如果流确实需要关闭,则可以在try
-with-resources语句中将其声明为资源。)流管线可以按顺序或并行执行 。这个执行模式是流的一个属性。流是通过顺序或并行执行的初始选择创建的。(例如,
Collection.stream()
创建一个顺序流,并Collection.parallelStream()
创建一个并行流。)执行模式的这种选择可以由BaseStream.sequential()
orBaseStream.parallel()
方法修改 ,并且可以用该BaseStream.isParallel()
方法查询。- 以来:
- 1.8
- 也可以看看:
-
IntStream
,LongStream
,DoubleStream
, java.util.stream
嵌套类摘要
嵌套类
修饰符和类型 界面和说明 static interface
Stream.Builder<T>
一个可变的建设者Stream
。
方法摘要
所有方法静态方法实例方法抽象方法默认方法
修饰符和类型 方法和描述 boolean
allMatch(Predicate<? super T> predicate)
返回此流的所有元素是否与提供的谓词匹配。boolean
anyMatch(Predicate<? super T> predicate)
返回此流的任何元素是否与提供的谓词匹配。static <T> Stream.Builder<T>
builder()
返回一个生成器Stream
。<R,A> R
collect(Collector<? super T,A,R> collector)
使用a对此流的元素执行可变减少操作Collector
。<R> R
collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
对此流的元素执行可变减少操作。static <T> Stream<T>
concat(Stream<? extends T> a, Stream<? extends T> b)
创建一个延迟连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。long
count()
返回此流中元素的数量。Stream<T>
distinct()
返回Object.equals(Object)
由此流的不同元素(根据 )组成的流。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)
返回一个流,该流包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。DoubleStream
flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
返回一个DoubleStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。IntStream
flatMapToInt(Function<? super T,? extends IntStream> mapper)
返回一个IntStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。LongStream
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<T> s)
返回无限顺序无序流,其中每个元素由提供的生成Supplier
。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)
返回由将给定函数应用于此流的元素的结果组成的流。DoubleStream
mapToDouble(ToDoubleFunction<? super T> mapper)
返回DoubleStream
由给定函数应用于此流的元素的结果组成的结果。IntStream
mapToInt(ToIntFunction<? super T> mapper)
返回IntStream
由将给定函数应用于此流的元素的结果组成的结果。LongStream
mapToLong(ToLongFunction<? super T> mapper)
返回LongStream
由给定函数应用于此流的元素的结果组成的结果。Optional<T>
max(Comparator<? super T> comparator)
根据提供的内容返回此流的最大元素Comparator
。Optional<T>
min(Comparator<? super T> comparator)
根据提供的返回此流的最小元素Comparator
。boolean
noneMatch(Predicate<? super T> predicate)
返回此流的元素是否与提供的谓词匹配。static <T> Stream<T>
of(T... values)
返回一个顺序排列的流,其元素是指定的值。static <T> Stream<T>
of(T t)
返回Stream
包含单个元素的顺序。Stream<T>
peek(Consumer<? super T> action)
返回由此流的元素组成的流,另外对每个元素执行提供的操作,因为元素将从结果流中消耗。Optional<T>
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)
使用提供的身份,积累和组合功能,执行此流的元素缩减。Stream<T>
skip(long n)
丢弃流的第一个n
元素后,返回包含此流的其余元素的流。Stream<T>
sorted()
返回由此流的元素组成的流,按照自然顺序排序。Stream<T>
sorted(Comparator<? super T> comparator)
返回由该流的元素组成的流,按照提供的顺序进行排序Comparator
。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)
返回由此流的元素组成的流,该流匹配给定的谓词。这是一个中间操作。
- 参数:
-
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
在其内容被放入这个流之后。(如果使用映射的流是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(" +")));
mapper
传递 的函数flatMap
使用一个简单的正则表达式将行分割成一个单词数组,然后从该数组创建一个单词流。 - 类型参数:
-
R
- 新流的元素类型 - 参数:
-
mapper
-一个非干扰, 无状态 功能应用到其产生新的值的流的每个元素 - 返回:
- 新的流
flatMapToInt
IntStream flatMapToInt(Function <?super T,?extends IntStream > mapper)
返回一个IntStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射的流都是closed
在其内容被放入这个流之后。(如果使用映射的流是null
一个空的流,则改为)。这是一个中间操作。
- 参数:
-
mapper
-一个非干扰, 无状态 功能应用到其产生新的值的流的每个元素 - 返回:
- 新的流
- 也可以看看:
-
flatMap(Function)
flatMapToLong
LongStream flatMapToLong(Function <?super T,?extends LongStream > mapper)
返回一个LongStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射的流都是closed
在其内容被放入这个流之后。(如果使用映射的流是null
一个空的流,则改为)。这是一个中间操作。
- 参数:
-
mapper
-一个非干扰, 无状态 功能应用到其产生新的值的流的每个元素 - 返回:
- 新的流
- 也可以看看:
-
flatMap(Function)
flatMapToDouble
DoubleStream flatMapToDouble(Function <?super T,?extends DoubleStream > mapper)
返回一个DoubleStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射的流都是closed
在其内容已被放入该流之后。(如果使用映射的流是null
一个空的流,则改为)。这是一个中间操作。
- 参数:
-
mapper
-一个非干扰, 无状态 功能应用到其产生新的值的流的每个元素 - 返回:
- 新的流
- 也可以看看:
-
flatMap(Function)
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
执行终端操作时可能会抛出a 。对于有序的流,排序是稳定的。对于无序流,没有稳定性保证。
这是一个有状态的中间操作。
- 返回:
- 新的流
sorted
Stream<T> sorted(Comparator<? super T> 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());
- 参数:
-
action
- 从流中消耗的对元素执行的无干扰操作 - 返回:
- 新的流
limit
Stream<T> limit(long maxSize)
返回由此流的元素组成的流,截断的maxSize
长度不得超过。这是一个短路状态中间操作。
- API注意:
-
虽然
limit()
在顺序流管道上通常是一个便宜的操作,但是在有序并行流水线上,特别是对于大数值,这可能是非常昂贵的maxSize
,因为limit(n)
不仅要返回任何n个元素,还要返回遇到顺序中的 前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个元素,而且还跳过遇到次序中的 前n个元素。如果您的情况的语义允许,使用无序的流源(如generate(Supplier)
)或删除排序约束BaseStream.unordered()
可能会导致skip()
并行管道的显着加速。如果要求与遇到命令的一致性,并且skip()
在并行管道中遇到性能不佳或内存利用率 较低的问题,则切换到顺序执行BaseStream.sequential()
可能会提高性能。 - 参数:
-
n
- 要跳过的主要元素的数量 - 返回:
- 新的流
- 抛出:
-
IllegalArgumentException
- 如果n
是消极的
forEach
void forEach(Consumer <?super T > action)
对此流的每个元素执行操作。这是一个终端操作。
这个操作的行为显然是不确定的。对于并行流管道,这个操作并不能 保证尊重流的相遇顺序,因为这样做会牺牲并行的利益。对于任何给定的元素,该动作可以在任何时间和在图书馆选择的任何线程中执行。如果操作访问共享状态,则负责提供所需的同步。
- 参数:
-
action
- 对元素执行的无干扰行为
forEachOrdered
void forEachOrdered(Consumer <?super T > action)
为流的每个元素执行操作,如果流具有已定义的遇到顺序,则按流的遇到顺序执行操作。这是一个终端操作。
这个操作一次处理一个元素,如果存在的话,按照顺序处理。执行一个元素的动作 发生在 为后续元素执行动作之前,但是对于任何给定的元素,动作可以在库选择的任何线程中执行。
- 参数:
-
action
- 对元素执行的无干扰行为 - 也可以看看:
-
forEach(Consumer)
toArray
Object [] toArray()
返回包含此流的元素的数组。这是一个终端操作。
- 返回:
- 包含此流的元素的数组
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
值必须是累加器函数的标识。这意味着,所有t
,accumulator.apply(identity, t)
等于t
。该accumulator
函数必须是一个 关联函数。这是一个终端操作。
- API注意:
-
总和,最小值,最大值,平均值和字符串连接都是特殊的缩减情况。总结一串数字可以表示为:
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;}elseresult = accumulator.apply(result, element);}return foundAny ? Optional.of(result) : Optional.empty();
但不限制顺序执行。
该
accumulator
函数必须是一个 关联函数。这是一个终端操作。
- 参数:
-
accumulator
- 用于组合两个值的关联, 无干扰, 无状态函数 - 返回:
-
一个
Optional
描述减少的结果 - 抛出:
-
NullPointerException
- 如果减少的结果为空 - 也可以看看:
-
reduce(Object, BinaryOperator)
,min(Comparator)
,max(Comparator)
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
值必须是组合函数的标识。这意味着,所有u
,combiner(identity, u)
等于u
。此外,该combiner
功能必须与该accumulator
功能兼容; 对于所有u
和t
,以下必须持有:combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
这是一个终端操作。
- API注意:
-
许多减少使用这种形式可以更简单地通过明确的组合
map
和reduce
操作来表示。该accumulator
函数作为一个融合的映射器和累加器,有时比单独的映射和减少更有效率,比如知道以前减少的值可以避免一些计算。 - 类型参数:
-
U
- 结果的类型 - 参数:
-
identity
- 组合函数的标识值 -
accumulator
-一个缔合, 非干扰性, 无状态 用于将一个额外的元件到结果函数 -
combiner
-一个缔合, 非干扰, 无状态 功能用于组合两个值,它必须与蓄能器功能兼容 - 返回:
- 减少的结果
- 也可以看看:
-
reduce(BinaryOperator)
,reduce(Object, BinaryOperator)
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
-一个缔合, 非干扰, 无状态 功能用于组合两个值,它必须与蓄能器功能兼容 - 返回:
- 减少的结果
collect
<R,A> R collect(Collector<? super T,A,R> collector)
使用a对此流的元素执行可变减少操作Collector
。ACollector
将用作参数的函数封装起来collect(Supplier, BiConsumer, BiConsumer)
,从而允许重用收集策略和收集操作的组合,例如多级分组或分区。如果流是平行的,并且
Collector
是concurrent
,并且或者流是无序或集电极是unordered
,那么将执行一个并发减少(见Collector
用于并发还原细节)。这是一个终端操作。
当并行执行时,可以实例化,填充和合并多个中间结果,以保持可变数据结构的隔离。因此,即使与非线程安全的数据结构(如
ArrayList
)并行执行,并行还原也不需要额外的同步。- API注意:
-
以下将把字符串累加到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
。这是减少的特殊情况 。这是一个终端操作。
- 参数:
-
comparator
- 一个无干扰, 无状态Comparator
的比较这个流的元素 - 返回:
-
一个
Optional
描述该流的最小元素,或空Optional
如果流是空 - 抛出:
-
NullPointerException
- 如果最小元素为null
max
Optional<T> max(Comparator<? super T> comparator)
根据提供的内容返回此流的最大元素Comparator
。这是减少的特殊情况 。这是一个终端操作。
- 参数:
-
comparator
- 一个无干扰, 无状态Comparator
的比较这个流的元素 - 返回:
-
一个
Optional
描述该流的最大元素,或空Optional
如果流是空 - 抛出:
-
NullPointerException
- 如果最大元素为空
count
long count()
返回此流中元素的数量。这是一个特殊的情况下降低,等同于:return mapToLong(e -> 1L).sum();
这是一个终端操作。
- 返回:
- 这个流中元素的数量
anyMatch
boolean anyMatch(Predicate<? super T> predicate)
返回此流的任何元素是否与提供的谓词匹配。如果不需要确定结果,则不能评估所有元素的谓词。如果流是空的,则false
返回并且不评估谓词。这是一个短路终端操作。
- API注意:
- 这种方法评估流的元素上谓词的存在量化(对于一些x P(x))。
- 参数:
-
predicate
- 适用于这个流的元素的一个无干扰, 无状态的谓词 - 返回:
-
true
如果流的任何元素与提供的谓词匹配,否则false
allMatch
boolean allMatch(Predicate<? super T> predicate)
返回此流的所有元素是否与提供的谓词匹配。如果不需要确定结果,则不能评估所有元素的谓词。如果流是空的,则true
返回并且不评估谓词。这是一个短路终端操作。
- API注意:
-
这种方法评估流的元素的谓词的通用量化(对于所有x P(x))。如果流是空的,量化被认为是真实的满足,并且总是
true
(不管P(x))。 - 参数:
-
predicate
- 适用于这个流的元素的一个无干扰, 无状态的谓词 - 返回:
-
true
如果流的所有元素都匹配提供的谓词,或者流是空的,否则false
noneMatch
boolean noneMatch(Predicate<? super T> predicate)
返回此流的元素是否与提供的谓词匹配。如果不需要确定结果,则不能评估所有元素的谓词。如果流是空的,则true
返回并且不评估谓词。这是一个短路终端操作。
- API注意:
-
这种方法评估流元素上的否定谓词的通用量化(对于所有x〜P(x))。如果流是空的,则量化被认为是真实地满足,并且总是
true
,不管P(x)如何。 - 参数:
-
predicate
- 适用于这个流的元素的一个无干扰, 无状态的谓词 - 返回:
-
true
如果流的任何元素都不匹配提供的谓词,或者流是空的,否则false
findFirst
Optional<T> findFirst()
- 返回:
-
一个
Optional
描述该流的第一个元素,或空Optional
如果流是空 - 抛出:
-
NullPointerException
- 如果选择的元素为空
findAny
Optional<T> findAny()
返回Optional
描述流的某个元素,Optional
如果流为空,则返回一个空元素。这是一个短路终端操作。
这个操作的行为是明确的不确定的; 它可以自由选择流中的任何元素。这是为了在并行操作中实现最高性能。成本是多个调用在同一来源可能不会返回相同的结果。(如果需要稳定的结果,请
findFirst()
改用。)- 返回:
-
一个
Optional
描述该流的某些元件,或者一个空Optional
如果流是空 - 抛出:
-
NullPointerException
- 如果选择的元素为空 - 也可以看看:
-
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
- 单个元素 - 返回:
- 一个单一的顺序流
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
。- 类型参数:
-
T
- 流元素的类型 - 参数:
-
seed
- 最初的元素 -
f
- 应用于前一个元素以生成新元素的函数 - 返回:
-
一个新的顺序
Stream
generate
static <T> Stream <T> generate(Supplier <T> s)
返回无限顺序无序流,其中每个元素由提供的生成Supplier
。这适用于生成恒定流,随机元素流等。- 类型参数:
-
T
- 流元素的类型 - 参数:
-
s
-Supplier
生成的元素 - 返回:
-
一个新的无限顺序无序
Stream
concat
static <T> Stream <T> concat(Stream <?extends T> a,Stream <?extends T> b)
创建一个延迟连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。如果两个输入流都是有序的,则生成的流是有序的;如果任意一个输入流是并行的,则生成的流是并行的。当结果流关闭时,调用两个输入流的关闭处理程序。- 实施说明:
-
从重复连接构造流时要小心。访问深度级联流的元素可能会导致深度调用链,甚至导致深度调用链
StackOverflowException
。 - 类型参数:
-
T
- 流元素的类型 - 参数:
-
a
- 第一个流 -
b
- 第二个流 - 返回:
- 两个输入流的连接
java8新特新:接口流-Stream()接口和所有方法(map,foreach,filter,count,distinct,limit,collect,skip,sorted)相关推荐
- 24.1 传统集合的多步遍历代码、Stream流更优写法与stream、forEach、filter、count、limit、skip、concat方法、静态方法:tream.of()
目录 1 传统集合的多步遍历代码 2 Stream的更优写法 3 Stream流 3.1 Stream流:获取流 列:单列集合.双列集合.数组获取stream流 3.2 Stream流中的常用方法:f ...
- java8新特性(4)— Stream流
java8新特性(4)- Stream流 遍历集合更强大 package com.common.jdk8;import java.util.*; import java.util.stream.Col ...
- java8 Lambda表达式的应用(函数式接口、lambda表达式,方法引用及Stream API)
之前写了一篇博客简单介绍了一下java 8发布新增的一些特性功能,java 8在2014年发布,距今也不少年了,但是lambda表达式使用并不熟练,现在一边学习,一边记录一下. 目录 一.Lambda ...
- java8新特性:三,Stream
java8新特性:三,Stream 1 Stream介绍 Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据. Stream 使用一种类似用 SQL 语句从数据 ...
- jpeg2000(j2k)图像编码解码:c++实现openjpeg内存流接口(memory stream)
前阵子用libjpeg-turbo实现jpeg图像在内存中编码与解码 参见<libjpeg:实现jpeg内存解压缩塈转换色彩空间/压缩分辨率>,<libjpeg:实现jpeg内存压缩 ...
- java8 流Stream 高级使用
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据. Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达 ...
- Java8 Stream 中的 reduce() 方法,执行聚合操作
初识 Stream 中的 reduce() 方法,是在最近一次刷算法题的过程中(下面会讲到),简洁干练的写法,让我眼前一亮. 所以,我简单学习了,总结了一下写法: 正文 Java 8 API添加了一个 ...
- jdk8新特性(接口新特性、lambda表达式、方法引用、函数式接口、Stream流)和单例设计模式
1.单例设计模式 1.概念: 设计模式:使用固有的流程或方式设计出来的类接口.枚举等元素 2.设计原则: 1.私有化构造方法[private.protected] 2.类中创建最终对象[唯一不能被赋值 ...
- Java8新特性学习(lambda,函数式接口,stream,Optional)
一. Lambda Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风格,使Jav ...
最新文章
- Python实战之logging模块使用详解
- Java基础知识强化之集合框架笔记76:ConcurrentHashMap之 ConcurrentHashMap简介
- knight tour java_The Knight’s tour problem
- linux如何扩展根分区,linux扩展根分区详细步骤
- erlang精要(14)-列表(1)
- boost::edge_list用法的测试程序
- Mybatis 中更新方法: updateByPrimaryKeySelective() 和 updateByPrimaryKey() 的区别
- 使用Fiddler查看APP的请求接口、接口参数和返回值的方法
- 董小姐宣布重磅升级:格力空调包修时长正式升级为10年
- python 输入列表 返回每个元素出现的次数
- 使用envi将遥感数据从uint16转为uint8
- 全面讲解在BIOS设置IDE设备的多种组合方式
- 中国机动渔船行业发展现状分析,生产渔船占据主导地位「图」
- matlab实现卷积编码与viterbi译码
- 革文B2B行业洞察:增长/存亡,中国医疗加速器第三方维保市场迷局
- win7c盘空间越来越小_C盘空间越来越小怎么办,5个步骤无损扩容1招就搞定
- 到处都在说直播连麦技术,它们真的能连吗?
- 联想第二季度业绩创纪录 所有业务实现强劲增长
- Excel2013利用图标集在单元格内加上各式各样的图标来表示状态
- Java实战干货分享
热门文章
- wget提示失败的解决办法
- javascript读写json示例
- ajax头文件报错,AJAX的CSRF保护
- 区块链BaaS云服务(14)华大BGI区块链“安全多方计算“
- C++ Primer 5th笔记(chap 14 重载运算和类型转换)输入和输出运算符
- 汉字输入练习 TypeChinese.java
- linux kernel的virtual kernel memory layout介绍(aarch64)
- [GKCTF 2021]XOR
- 最高标号预留与推进算法 --- 就是要比 Dinic 快!
- cad怎么调出科创易达绿化_【每日问答26】如何识别CAD图纸dwg格式版本?(内含往期)...