Java 8流手动短路[重复]
Posted
技术标签:
【中文标题】Java 8流手动短路[重复]【英文标题】:Java 8 stream short circuit manually [duplicate] 【发布时间】:2017-01-20 04:53:54 【问题描述】:有什么方法可以手动短路流(例如 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());
【问题讨论】:
相关:***.com/questions/20746429/… 你要的一般叫takewhile
。根据this question,似乎没有内置的方法可以做到这一点,但你可以自己写一个。
【参考方案1】:
根据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);
【讨论】:
与经典循环相比,这非常低效。 @aventurin 使用 java9 可能会有更快的实现。至少代码简洁,不需要临时变量。 流 API 可能会向程序员隐藏它背后的膨胀,但没有什么魔法可以减少 CPU 周期数、内存重新分配(ArrayList-collector)或额外的对象和类创建。除此之外,使用循环的等效代码更容易理解,只需要三行代码加上两个变量定义。 @aventurin 这不是问题的重点。但是,我的示例的问题陈述更大。我首先使用 while 循环对其进行编码,然后切换到流,因为我想增加对它们的了解。隐式版本:github.com/Journeycorner/tom-turbo-solver/commit/… 与功能版本:github.com/Journeycorner/tom-turbo-solver/blob/master/src/at/…。如果您可以用更少的代码行编写代码,而无需省略括号,请给我写一个拉取请求;)。以上是关于Java 8流手动短路[重复]的主要内容,如果未能解决你的问题,请参考以下文章