Java 8流手动短路

时间:2016-09-12 17:25:18

标签: performance java-8 java-stream short-circuiting

有没有办法手动短路流(比如在findFirst中)?

示例:

想象一下按字号和字母排序的大字典:

cat
... (many more)
lamp
mountain
... (many more)

当行大小超过4时,只准备并从头开始计算文件,立即返回

read cat, compute cat
...
read tree, compute lamp
read mountain, return

以下代码非常简洁,但没有利用流的顺序,它必须准备好每一行:

try (Stream<String> lines = Files.lines(Paths.get(DICTIONARY_PATH))) {
        return lines
                // filter for words with the correct size
                .filter(line -> line.length() == 4)
                // do stuff...
                .collect(Collectors.toList());
}

1 个答案:

答案 0 :(得分:0)

基于Limit a stream by a predicate的答案,当谓词返回false时,处理正确停止。希望这种方法可以在Java 9中找到:

private static List<String> getPossibleAnswers(int numberOfChars, char[][] possibleChars) throws IOException {
    try (Stream<String> lines = Files.lines(Paths.get(DICTIONARY_PATH)) {
        return takeWhile(lines, line -> line.length() <= numberOfChars)
                // filter length
                .filter(line -> line.length() == numberOfChars)
                // do stuff
                .collect(Collectors.toList());
    }
}

static <T> Spliterator<T> takeWhile(Spliterator<T> splitr, Predicate<? super T> predicate) {
    return new Spliterators.AbstractSpliterator<T>(splitr.estimateSize(), 0) {              boolean stillGoing = true;

        @Override
        public boolean tryAdvance(Consumer<? super T> consumer) {
            if (stillGoing) {
                boolean hadNext = splitr.tryAdvance(elem -> {
                    if (predicate.test(elem)) {
                        consumer.accept(elem);
                    } else {
                        stillGoing = false;
                    }
                });
                return hadNext && stillGoing;
            }
            return false;
        }
    };
}

static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> predicate) {
    return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
}