Java 8流手动短路
Java 8 stream short circuit manually
有什么方法可以手动使流短路(如在 findFirst 中)?
示例:
想象一本按单词大小和字母排序的巨大字典:
cat
... (many more)
lamp
mountain
... (many more)
仅准备好并从头开始计算文件,return当行大小超过 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());
}
答案基于Limit a stream by a predicate, processing correctly stops when predicate returns false. Hopefully this method comes available in 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);
}
有什么方法可以手动使流短路(如在 findFirst 中)?
示例:
想象一本按单词大小和字母排序的巨大字典:
cat
... (many more)
lamp
mountain
... (many more)
仅准备好并从头开始计算文件,return当行大小超过 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());
}
答案基于Limit a stream by a predicate, processing correctly stops when predicate returns false. Hopefully this method comes available in 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);
}