相关疑难解决方法(0)

如何检查Java 8 Stream是否为空?

Stream作为非终端操作,如何检查a 是否为空并抛出异常(如果不是)?

基本上,我正在寻找与下面的代码等效的东西,但没有实现中间的流.特别是,在终端操作实际消耗流之前不应进行检查.

public Stream<Thing> getFilteredThings() {
    Stream<Thing> stream = getThings().stream()
                .filter(Thing::isFoo)
                .filter(Thing::isBar);
    return nonEmptyStream(stream, () -> {
        throw new RuntimeException("No foo bar things available")   
    });
}

private static <T> Stream<T> nonEmptyStream(Stream<T> stream, Supplier<T> defaultValue) {
    List<T> list = stream.collect(Collectors.toList());
    if (list.isEmpty()) list.add(defaultValue.get());
    return list.stream();
}
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

83
推荐指数
6
解决办法
7万
查看次数

Stream.spliterator对并行流的奇怪行为

我正在使用流分裂器直接用于我正在编写的库中的低级操作.最近,当我使用流分裂器和交错tryAdvance/trySplit调用时,我发现了非常奇怪的行为.这是一个简单的代码,演示了这个问题:

import java.util.Arrays;
import java.util.Spliterator;

public class SpliteratorBug {
    public static void main(String[] args) {
        Integer[][] input = { { 1 }, { 2, 3 }, { 4, 5, 6 }, { 7, 8 }, { 9 } };
        Spliterator<Integer> spliterator = Arrays.stream(input).parallel()
                .flatMap(Arrays::stream).spliterator();
        spliterator.trySplit();
        spliterator.tryAdvance(s -> {});
        spliterator.trySplit();
        spliterator.forEachRemaining(System.out::println);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是

5
6
9
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,后平映射我应该得到连续编号的有序流19.我将分裂器分开一次,所以它应该跳到一些中间位置.接下来我从中消耗一个元素并将其拆分一次.之后我打印所有剩余的元素.我希望我将从流尾部有几个连续的元素(可能是零元素,它也会很好).然而我所得到的是56,然后突然跳出来9.

我知道目前在JDK分裂器中并没有这样使用:它们总是在遍历之前分裂.但是官方文档没有明确禁止调用trySplittryAdvance.

当我使用直接从集合,数组,生成的源等创建的spliterator时,从未观察到这个问题.只有当spliterator是从具有中间体的并行流创建时才会观察到flatMap.

所以问题是:我是否遇到了这个错误,或者明确禁止某个地方以这种方式使用分裂器?

java java-8 java-stream spliterator

10
推荐指数
2
解决办法
589
查看次数

标签 统计

java ×2

java-8 ×2

java-stream ×2

spliterator ×1