neX*_*Xus 2 java-8 java-stream
注意:我不一定在寻找下面描述的具体示例问题的解决方案.我真的很感兴趣为什么在Java 8中不可能开箱即用.
Java流是懒惰的.最后他们有一个终端操作.
我的解释是这个终端操作将通过流提取所有值.没有任何中间操作可以做到这一点.为什么没有中间操作通过流引入任意数量的元素?像这样的东西:
stream
.mapMultiple(this::consumeMultipleElements) // or groupAndMap or combine or intermediateCollect or reverseFlatMap
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
当下游操作尝试使流一次前进时,中间操作可能尝试多次上行(或根本不上行).
我会看到几个用例:(
这些只是示例.所以你可以看到它确实可以处理这些用例,但它不是"流式传输方式",而且这些解决方案缺乏Streams所具有的理想的懒惰属性. )
将多个元素组合到一个新元素中,以传递到流的其余部分.(例如,成对(1,2,3,4,5,6) ? ((1,2),(3,4),(5,6)))
// Something like this,
// without needing to consume the entire stream upfront,
// and also more generic. (The combiner should decide for itself how many elements to consume/combine per resulting element. Maybe the combiner is a Consumer<Iterator<E>> or a Consumer<Supplier<E>>)
public <E, R> Stream<R> combine(Stream<E> stream, BiFunction<E, E, R> combiner) {
List<E> completeList = stream.collect(toList());
return IntStream.range(0, completeList.size() / 2)
.mapToObj(i -> combiner.apply(
completeList.get(2 * i),
completeList.get(2 * i + 1)));
}
Run Code Online (Sandbox Code Playgroud)确定Stream是否为空(将Stream映射到可选的非空流)
// Something like this, without needing to consume the entire stream
public <E> Optional<Stream<E>> toNonEmptyStream(Stream<E> stream) {
List<E> elements = stream.collect(toList());
return elements.isEmpty()
? Optional.empty()
: Optional.of(elements.stream());
}
Run Code Online (Sandbox Code Playgroud)拥有一个Iterator不会终止流的惰性(允许基于更复杂的逻辑跳过元素skip(long n)).
Iterator<E> iterator = stream.iterator();
// Allow this without throwing a "java.lang.IllegalStateException: stream has already been operated upon or closed"
stream.collect(toList());
Run Code Online (Sandbox Code Playgroud)当他们设计Streams及其周围的一切时,他们是否忘记了这些用例,还是明确地将其删除了?
我知道在处理并行流时这些可能会产生意想不到的结果,但在我看来,这是一个可以记录的风险.
那么你想要的所有操作实际上都可以实现Stream API,但不是开箱即用的.
将多个元素组合成元素对 - 您需要一个自定义Spliterator.这是Tagir Valeev这样做的.他有一个绝对的图书馆野兽叫做StreamEx许多其他有用的东西,不支持开箱即用.
我不明白你的第二个例子,但我敢打赌它也是可行的.
skip一个更复杂的操作是在java-9通过dropWhile与takeWhile该采取Predicate作为输入.
请注意,当你说没有任何中间操作可以做到这一点时,这是不准确的 - 确实存在sorted并且distinct确实如此.否则他们无法工作.也有flatMap这样的行为,但这更像是一个错误.
还有一件事是并行流的中间操作没有定义的顺序,因此这种有状态的中间操作将具有并行流的未知条目.另一方面,您总是可以选择滥用以下内容:
List<Something> list = Collections.synchronizedList()
.map(x -> {
list.add(x);
// your mapping
})
Run Code Online (Sandbox Code Playgroud)
如果我是你并且真的认为我可能需要那个,我不会这样做,但为了以防万一......
| 归档时间: |
|
| 查看次数: |
210 次 |
| 最近记录: |