T
- 流元素的类型
公共接口Stream扩展BaseStream Stream >
Stream
and 的聚合操作
IntStream
:
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
在这个例子中,
widgets
是一个
Collection
。我们通过创建一个
Widget
对象流
Collection.stream()
,对其进行过滤以产生只包含红色小部件的流,然后将其转换为
int
代表每个红色小部件权重的值流。然后将这个流加起来产生总重量。
除了Stream
,这是对象引用的流,存在用于原始特IntStream
,LongStream
以及DoubleStream
,所有这些都称为“流”和符合此处描述的特征和限制。
为了执行计算,流 操作被组成 流管道。一个流管道由一个源(可能是一个数组,一个集合,一个生成器函数,一个I / O通道等),零个或多个中间操作(将流转换成另一个流等filter(Predicate)
) 终端操作(产生结果或副作用,如count()
or forEach(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()
or BaseStream.parallel()
方法修改 ,并且可以用该BaseStream.isParallel()
方法查询。
IntStream
,
LongStream
,
DoubleStream
, java.util.stream
修饰符和类型 | 界面和说明 |
---|---|
static interface |
Stream.Builder
一个可变的建设者
Stream
。
|
修饰符和类型 | 方法和描述 |
---|---|
boolean |
allMatch(Predicate super T> predicate)
返回此流的所有元素是否与提供的谓词匹配。
|
boolean |
anyMatch(Predicate super T> predicate)
返回此流的任何元素是否与提供的谓词匹配。
|
static |
builder()
返回一个生成器
Stream
。
|
|
collect(Collector super T,A,R> collector)
使用a对此流的元素执行
可变减少
操作
Collector
。
|
|
collect(Supplier
对此流的元素执行
可变减少
操作。
|
static |
concat(Stream extends T> a, Stream extends T> b)
创建一个延迟连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。
|
long |
count()
返回此流中元素的数量。
|
Stream |
distinct()
返回
Object.equals(Object)
由此流的不同元素(根据 )组成的流。
|
static |
empty()
返回一个空的顺序
Stream
。
|
Stream |
filter(Predicate super T> predicate)
返回由此流的元素组成的流,该流匹配给定的谓词。
|
Optional |
findAny()
返回
Optional
描述流的某个元素,
Optional
如果流为空,则返回一个空元素。
|
Optional |
findFirst()
返回
Optional
描述此流的第一个元素,
Optional
如果流为空,则返回空。
|
|
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 |
generate(Supplier
返回无限顺序无序流,其中每个元素由提供的生成
Supplier
。
|
static |
iterate(T seed, UnaryOperator
返回一个无限连续有序
Stream
通过函数的迭代应用产生
f
为初始元素
seed
,产生
Stream
包括
seed
,
f(seed)
,
f(f(seed))
,等。
|
Stream |
limit(long maxSize)
返回由此流的元素组成的流,截断的
maxSize
长度不得超过。
|
|
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 |
max(Comparator super T> comparator)
根据提供的内容返回此流的最大元素
Comparator
。
|
Optional |
min(Comparator super T> comparator)
根据提供的返回此流的最小元素
Comparator
。
|
boolean |
noneMatch(Predicate super T> predicate)
返回此流的元素是否与提供的谓词匹配。
|
static |
of(T... values)
返回一个顺序排列的流,其元素是指定的值。
|
static |
of(T t)
返回
Stream
包含单个元素的顺序。
|
Stream |
peek(Consumer super T> action)
返回由此流的元素组成的流,另外对每个元素执行提供的操作,因为元素将从结果流中消耗。
|
Optional |
reduce(BinaryOperator
使用关联累积函数执行此流的元素
缩减
,并返回描述缩小的值(如果有的话)。
Optional
|
T |
reduce(T identity, BinaryOperator
使用提供的标识值和关联 累积函数执行此流的元素
缩减
,并返回缩小的值。
|
U |
reduce(U identity, BiFunction accumulator, BinaryOperator combiner)
使用提供的身份,积累和组合功能,执行此流的元素
缩减
。
|
Stream |
skip(long n)
丢弃流的第一个
n
元素后,返回包含此流的其余元素的流。
|
Stream |
sorted()
返回由此流的元素组成的流,按照自然顺序排序。
|
Stream |
sorted(Comparator super T> comparator)
返回由该流的元素组成的流,按照提供的顺序进行排序
Comparator
。
|
Object[] |
toArray()
返回包含此流的元素的数组。
|
A[] |
toArray(IntFunction generator)
返回包含此流的元素的数组,使用提供的
generator
函数分配返回的数组,以及分区执行或调整大小时可能需要的其他数组。
|
close, isParallel, iterator, onClose, parallel, sequential, spliterator, unordered
Streamfilter(Predicate super T> predicate)
这是一个中间操作。
predicate
- 适用于每个元素的 非干扰
, 无状态
谓词,以确定是否应该包含它
Stream map(Function super T,? extends R> mapper)
这是一个中间操作。
R
- 新流的元素类型
mapper
-一个 无干扰
, 无状态的
功能应用到每个元素
IntStream mapToInt(ToIntFunction <?super T > mapper)
IntStream
由将给定函数应用于此流的元素的结果组成的结果。
这是一个 中间操作。
mapper
-一个 无干扰
, 无状态的
功能应用到每个元素
LongStream mapToLong(ToLongFunction <?super T > mapper)
LongStream
由给定函数应用于此流的元素的结果组成的结果。
这是一个中间操作。
mapper
-一个 无干扰
, 无状态的
功能应用到每个元素
DoubleStream mapToDouble(ToDoubleFunction <?super T > mapper)
DoubleStream
由给定函数应用于此流的元素的结果组成的结果。
这是一个中间操作。
mapper
-一个 无干扰
, 无状态的
功能应用到每个元素
Stream flatMap(Function super T,? extends Stream extends R>> mapper)
closed
在其内容被放入这个流之后。(如果使用映射的流是
null
一个空的流,则改为)。
这是一个中间操作。
flatMap()
操作具有对流的元素应用一对多转换,然后将所得元素平坦化为新流的效果。
例子。
如果orders
是采购订单流,并且每个采购订单都包含一系列行项目,则以下内容会生成包含所有订单中的所有行项目的流:
orders.flatMap(order -> order.getLineItems().stream())...
如果path
是文件的路径,则以下内容将生成words
包含在该文件中的一个流:
Stream lines = Files.lines(path, StandardCharsets.UTF_8);
Stream words = lines.flatMap(line -> Stream.of(line.split(" +")));
mapper
传递 的函数
flatMap
使用一个简单的正则表达式将行分割成一个单词数组,然后从该数组创建一个单词流。
R
- 新流的元素类型
mapper
-一个 非干扰
, 无状态
功能应用到其产生新的值的流的每个元素
IntStream flatMapToInt(Function <?super T,?extends IntStream > mapper)
IntStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射的流都是
closed
在其内容被放入这个流之后。(如果使用映射的流是
null
一个空的流,则改为)。
这是一个中间操作。
mapper
-一个 非干扰
, 无状态
功能应用到其产生新的值的流的每个元素
flatMap(Function)
LongStream flatMapToLong(Function <?super T,?extends LongStream > mapper)
LongStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射的流都是
closed
在其内容被放入这个流之后。(如果使用映射的流是
null
一个空的流,则改为)。
这是一个中间操作。
mapper
-一个 非干扰
, 无状态
功能应用到其产生新的值的流的每个元素
flatMap(Function)
DoubleStream flatMapToDouble(Function <?super T,?extends DoubleStream > mapper)
DoubleStream
包含将此流的每个元素替换为通过将所提供的映射函数应用于每个元素而生成的映射流的内容的结果。每个映射的流都是
closed
在其内容已被放入该流之后。(如果使用映射的流是
null
一个空的流,则改为)。
这是一个中间操作。
mapper
-一个 非干扰
, 无状态
功能应用到其产生新的值的流的每个元素
flatMap(Function)
Stream < T > distinct()
Object.equals(Object)
由此流的不同元素(根据 )组成的流。
对于有序流,选择不同的元素是稳定的(对于重复的元素,保持在遇到顺序中首先出现的元素)。对于无序流,没有稳定性保证。
这是一个有状态的中间操作。
distinct()
在并行管道中保持稳定性是相对昂贵的(要求操作充当完全屏障,具有大量的缓冲开销),并且通常不需要稳定性。如果您的情况的语义允许,使用无序的流源(如
generate(Supplier)
)或删除排序约束
BaseStream.unordered()
可能会导致
distinct()
在并行管道中显着更高效的执行。如果要求与遇到命令的一致性,并且
distinct()
在并行管道中遇到性能不佳或内存利用率较低的问题,则切换到顺序执行
BaseStream.sequential()
可能会提高性能。
Stream < T > sorted()
Comparable
,
java.lang.ClassCastException
执行终端操作时可能会抛出a 。
对于有序的流,排序是稳定的。对于无序流,没有稳定性保证。
这是一个有状态的中间操作。
Streamsorted(Comparator super T> comparator)
Comparator
。
对于有序的流,排序是稳定的。对于无序流,没有稳定性保证。
这是一个有状态的中间操作。
comparator
- 用于比较流元素的无 干扰
, 无状态
Comparator
Stream < T > peek(Consumer <?super T > action)
这是一个中间操作。
对于并行流管线,可以在任何时间和任何线程中通过上游操作来调用该操作。如果操作修改共享状态,则负责提供所需的同步。
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
- 从流中消耗的对元素执行的 无干扰
操作
Streamlimit(long maxSize)
maxSize
长度不得超过。
这是一个短路状态中间操作。
limit()
在顺序流管道上通常是一个便宜的操作,但是在有序并行流水线上,特别是对于大数值,这可能是非常昂贵的
maxSize
,因为
limit(n)
不仅要返回任何
n个
元素,还要返回遇到顺序中的
前n个
元素。如果您的情况的语义允许,使用无序的流源(如
generate(Supplier)
)或删除排序约束
BaseStream.unordered()
可能会导致
limit()
并行管道的显着加速。如果要求与遇到命令的一致性,并且
limit()
在并行管道中遇到性能不佳或内存利用率 较低的问题,则切换到顺序执行
BaseStream.sequential()
可能会提高性能。
maxSize
- 流应该被限制的元素的数量
IllegalArgumentException
- 如果
maxSize
是消极的
Stream < T > skip(long n)
n
元素后,返回包含此流的其余元素的流。如果这个流包含少于
n
元素,那么将返回一个空的流。
这是一个有状态的中间操作。
skip()
在顺序流管线上通常是一个便宜的操作,但对于有序的并行流水线,特别是对于大数值,这可能是非常昂贵的
n
,因为
skip(n)
被约束不仅跳过任何
n个
元素,而且还跳过遇到次序中的
前n个
元素。如果您的情况的语义允许,使用无序的流源(如
generate(Supplier)
)或删除排序约束
BaseStream.unordered()
可能会导致
skip()
并行管道的显着加速。如果要求与遇到命令的一致性,并且
skip()
在并行管道中遇到性能不佳或内存利用率 较低的问题,则切换到顺序执行
BaseStream.sequential()
可能会提高性能。
n
- 要跳过的主要元素的数量
IllegalArgumentException
- 如果
n
是消极的
void forEach(Consumer <?super T > action)
这是一个终端操作。
这个操作的行为显然是不确定的。对于并行流管道,这个操作并不能 保证尊重流的相遇顺序,因为这样做会牺牲并行的利益。对于任何给定的元素,该动作可以在任何时间和在图书馆选择的任何线程中执行。如果操作访问共享状态,则负责提供所需的同步。
action
- 对元素执行的 无干扰
行为
void forEachOrdered(Consumer <?super T > action)
这是一个终端操作。
这个操作一次处理一个元素,如果存在的话,按照顺序处理。执行一个元素的动作 发生在 为后续元素执行动作之前,但是对于任何给定的元素,动作可以在库选择的任何线程中执行。
action
- 对元素执行的 无干扰
行为
forEach(Consumer)
Object [] toArray()
这是一个终端操作。
A[] toArray(IntFunction generator)
generator
函数分配返回的数组,以及分区执行或调整大小时可能需要的其他数组。
这是一个终端操作。
Person[] men = people.stream()
.filter(p -> p.getGender() == MALE)
.toArray(Person[]::new);
A
- 结果数组的元素类型
generator
- 一个产生所需类型和提供长度的新数组的函数
ArrayStoreException
- 如果从数组生成器返回的数组的运行时类型不是该流中每个元素的运行时类型的超类型
T reduce(T identity, BinaryOperatoraccumulator)
T result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
但不限制顺序执行。
该identity
值必须是累加器函数的标识。这意味着,所有t
, accumulator.apply(identity, t)
等于t
。该accumulator
函数必须是一个 关联函数。
这是一个终端操作。
Integer sum = integers.reduce(0, (a, b) -> a+b);
要么:
Integer sum = integers.reduce(0, Integer::sum);
虽然这可能看起来是一个更简单的方法来执行聚合,而不是简单地将循环中的运行总量进行变异,但是减少操作可以更加平滑地进行并行处理,而不需要额外的同步,并且大大降低了数据竞争的风险。
identity
- 积累函数的标识值
accumulator
- 用于组合两个值的 关联
, 无干扰
, 无状态
函数
Optionalreduce(BinaryOperator 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(Object, BinaryOperator)
,
min(Comparator)
,
max(Comparator)
U reduce(U identity, BiFunction accumulator, BinaryOperator 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)
这是一个终端操作。
map
和
reduce
操作来表示。该
accumulator
函数作为一个融合的映射器和累加器,有时比单独的映射和减少更有效率,比如知道以前减少的值可以避免一些计算。
U
- 结果的类型
identity
- 组合函数的标识值
accumulator
-一个 缔合
, 非干扰性
, 无状态
用于将一个额外的元件到结果函数
combiner
-一个 缔合
, 非干扰
, 无状态
功能用于组合两个值,它必须与蓄能器功能兼容
reduce(BinaryOperator)
,
reduce(Object, BinaryOperator)
R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
ArrayList
,通过更新结果的状态而不是通过替换结果来结合元素。这产生了等同于下面的结果:
R result = supplier.get();
for (T element : this stream)
accumulator.accept(result, element);
return result;
就像reduce(Object, BinaryOperator)
,collect
操作可以并行,而不需要额外的同步。
这是一个终端操作。
collect()
。例如,以下内容将把字符串累加到
ArrayList
:
List asList = stringStream.collect(ArrayList::new, ArrayList::add,
ArrayList::addAll);
以下内容将获取一串字符串并将它们连接成一个字符串:
String concat = stringStream.collect(StringBuilder::new, StringBuilder::append,
StringBuilder::append)
.toString();
R
- 结果的类型
supplier
- 一个创建一个新的结果容器的函数。对于并行执行,可能会多次调用此函数,并且每次都必须返回一个新值。
accumulator
-一个 缔合
, 非干扰性
, 无状态
用于将一个额外的元件到结果函数
combiner
-一个 缔合
, 非干扰
, 无状态
功能用于组合两个值,它必须与蓄能器功能兼容
R collect(Collector super T,A,R> collector)
Collector
。A
Collector
将用作参数的函数封装起来
collect(Supplier, BiConsumer, BiConsumer)
,从而允许重用收集策略和收集操作的组合,例如多级分组或分区。
如果流是平行的,并且Collector
是concurrent
,并且或者流是无序或集电极是 unordered
,那么将执行一个并发减少(见Collector
用于并发还原细节)。
这是一个终端操作。
当并行执行时,可以实例化,填充和合并多个中间结果,以保持可变数据结构的隔离。因此,即使与非线程安全的数据结构(如ArrayList
)并行执行,并行还原也不需要额外的同步。
List asList = stringStream.collect(Collectors.toList());
以下将按Person
城市对对象进行分类:
Map> peopleByCity
= personStream.collect(Collectors.groupingBy(Person::getCity));
以下将按Person
州和城市分类对象,将两个对象级联Collector
在一起:
Map>> peopleByStateAndCity
= personStream.collect(Collectors.groupingBy(Person::getState,
Collectors.groupingBy(Person::getCity)));
R
- 结果的类型
A
- 的中间积累类型
Collector
collector
-
Collector
描述减少
collect(Supplier, BiConsumer, BiConsumer)
,
Collectors
Optionalmin(Comparator super T> comparator)
Comparator
。这是 减少
的特殊情况 。
这是一个终端操作。
comparator
- 一个 无干扰
, 无状态
Comparator
的比较这个流的元素
Optional
描述该流的最小元素,或空
Optional
如果流是空
NullPointerException
- 如果最小元素为null
Optionalmax(Comparator super T> comparator)
Comparator
。这是 减少
的特殊情况 。
这是一个终端操作。
comparator
- 一个 无干扰
, 无状态
Comparator
的比较这个流的元素
Optional
描述该流的最大元素,或空
Optional
如果流是空
NullPointerException
- 如果最大元素为空
long count()
return mapToLong(e -> 1L).sum();
这是一个终端操作。
boolean anyMatch(Predicate super T> predicate)
false
返回并且不评估谓词。
这是一个短路终端操作。
predicate
- 适用于这个流的元素的一个 无干扰
, 无状态的
谓词
true
如果流的任何元素与提供的谓词匹配,否则
false
boolean allMatch(Predicate super T> predicate)
true
返回并且不评估谓词。
这是一个短路终端操作。
true
(不管P(x))。
predicate
- 适用于这个流的元素的一个 无干扰
, 无状态的
谓词
true
如果流的所有元素都匹配提供的谓词,或者流是空的,否则
false
boolean noneMatch(Predicate super T> predicate)
true
返回并且不评估谓词。
这是一个短路终端操作。
true
,不管P(x)如何。
predicate
- 适用于这个流的元素的一个 无干扰
, 无状态的
谓词
true
如果流的任何元素都不匹配提供的谓词,或者流是空的,否则
false
OptionalfindFirst()
Optional
描述此流的第一个元素,
Optional
如果流为空,则返回空。如果流没有遇到命令,则可以返回任何元素。
这是一个短路终端操作。
Optional
描述该流的第一个元素,或空
Optional
如果流是空
NullPointerException
- 如果选择的元素为空
OptionalfindAny()
Optional
描述流的某个元素,
Optional
如果流为空,则返回一个空元素。
这是一个短路终端操作。
这个操作的行为是明确的不确定的; 它可以自由选择流中的任何元素。这是为了在并行操作中实现最高性能。成本是多个调用在同一来源可能不会返回相同的结果。(如果需要稳定的结果,请findFirst()
改用。)
Optional
描述该流的某些元件,或者一个空
Optional
如果流是空
NullPointerException
- 如果选择的元素为空
findFirst()
staticStream.Builder builder()
Stream
。
T
- 元素的类型
staticStream empty()
Stream
。
T
- 流元素的类型
staticStream of(T t)
Stream
包含单个元素的顺序。
T
- 流元素的类型
t
- 单个元素
@SafeVarargs staticStream of(T... values)
T
- 流元素的类型
values
- 新流的元素
staticStream iterate(T seed, UnaryOperatorf)
Stream
通过函数的迭代应用产生
f
为初始元素
seed
,产生
Stream
包括
seed
,
f(seed)
,
f(f(seed))
,等。
第一个元素(位置0
)Stream
将会是提供的seed
。为n > 0
,在位置上的元素 n
,将是将所述函数的结果f
在位置到元件n - 1
。
T
- 流元素的类型
seed
- 最初的元素
f
- 应用于前一个元素以生成新元素的函数
Stream
staticStream generate( Suppliers)
Supplier
。这适用于生成恒定流,随机元素流等。
T
- 流元素的类型
s
-
Supplier
生成的元素
Stream
staticStream concat( Stream <?extends T> a, Stream <?extends T> b)
StackOverflowException
。
T
- 流元素的类型
a
- 第一个流
b
- 第二个流