我知道每当我们在 <InputElement
mask="+7 (999) 999-99-99"
alwaysShowMask={true}
{...this.props}
maskChar=" "
/>
上拨打任何terminal method
时,它就会被关闭。
如果我们尝试在封闭流上调用任何其他终端函数,则会产生stream
。
但是,如果我们想要多次重复使用相同的流,该怎么办?
如何做到这一点?
答案 0 :(得分:2)
是的,它是Java 8流中重用流的重要原因
例如,对于任何终端操作,当操作关闭时,流将关闭。但是当我们在链中使用Stream时,我们可以避免这种异常:
正常终端操作:
Stream<String> stream =
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> s.startsWith("a"));
stream.anyMatch(s -> true); // ok
stream.noneMatch(s -> true); // exception
但如果我们使用:
而不是这个Supplier<Stream<String>> streamSupplier =
() -> Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> s.startsWith("a"));
streamSupplier.get().anyMatch(s -> true); // ok
streamSupplier.get().noneMatch(s -> true); // ok
这里.get()
“构造了一个新的流,并且只要它到达这一点就不会重用。
干杯!
答案 1 :(得分:0)
不,你不能重用Stream
,但是,如果不考虑重载堆空间,你可以在终端操作之前保存流的内容以便重用,使用{ {1}}。例如:
Stream.Builder
可以将流链接在一起,在每个连续的Stream<OriginalType> myStream = ...
Stream.Builder<SomeOtherType> copy = Stream.builder();
List<SomeOtherType> aList = myStream
.filter(...)
.map(...) // eventually maps to SomeOtherType
.peek(copy) // pour values into a new Stream
.collect(Collectors.toList());
Set<SomeOtherType> aSet = copy.build()
.collect(Collectors.toSet());
中添加一个新的Stream.Builder
实例。
不是您正在寻找的答案,但它确实避免了第二次进行管道操作的开销。它有自己的弱点,受限于堆空间,但它并没有Holger在他对Stream
解决方案的评论中提出的弱点 - 如果它是Supplier
流,它在第二次迭代中具有相同的值。
答案 2 :(得分:0)
尽管Java 8 Streams具有相当的功能,但它们并不是真正的反应性。没有多个终端操作。提及供应商的答案,使您可以编写看起来像有多个终端操作的代码,它们是完全独立生成的不同流上的终端。也就是说,时间复杂度没有改变。相当于写
Stream getStream() {
return Stream.of(....);
}
static void main() {
Values values1 = getStream().collect();
Values values2 = getStream().collect();
}
要进行多个终端操作的全部原因是为了节省计算量,而不是使其看起来不错。看一下https://github.com/ReactiveX/RxJava,它提供了真正的反应对象。
答案 3 :(得分:0)
不。您不能多次使用流。 您可以做的是,可以将流收集在列表中,然后可以调用map和forEach函数,该函数接受lambda。
List<String> list =
Stream.of("test")
.filter(s -> s.startsWith("a"))
.collect(Collectors.toList());
list.forEach(item -> item);
list.map(item -> item);
答案 4 :(得分:0)
一次对流元素进行 3 种不同的类似终端的操作的简单示例:
当然这不是很优雅,但确实有效:
List<Integer> famousNumbers = List.of(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55);
Stream<Integer> numbersStream = famousNumbers.stream();
Stream<Integer> numbersGreater5Stream = numbersStream.filter(x -> x > 5);
var ref = new Object() {
int counter = 0;
int sum = 0;
};
numbersGreater5Stream.forEach(x -> {
System.out.print(x + " ");
ref.counter++;
ref.sum += x;
});
System.out.println("\n" + ref.counter + " " + ref.sum);