我想不出创建 Stream
的好方法从头开始。假设例如(注意,下面的代码只是为了讨论的一个例子)
Matcher m = Pattern.compile(re).matcher(input);
List<String> matches = new ArrayList<>();
while (m.find())
matches.add(m.group());
并希望利用流 API。我想做一些类似的事情
List<String> matches = Stream.of(() -> m.find(), () -> m.group())
.collect(Collectors.toList());
其中 () -> m.find()
是一个判断是否有更多元素的函数,而 () -> m.group()
是一个函数提供下一个元素。
创建一个 Iterator
很容易,例如:
class MatchIterator implements Iterator<String> {
Matcher m;
boolean hasNext;
public MatchIterator(Matcher m) {
this.m = m;
hasNext = m.find();
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public String next() {
String next = m.group();
hasNext = m.find();
return next;
}
}
但我也想不出从迭代器创建流的简单方法。
编辑:我意识到我可以创建一个 Iterable
来创建 MatchIterator
(然后使用 StreamSupport
/Spliterator
) 但这需要我能够多次迭代源代码,因此它仍然不是一个通用的解决方案。
最佳答案
要创建一个Stream
,您需要一个Spliterator
。然后使用 StreamSupport.stream()
创建一个 Stream
。 (这是所有集合所做的。)
如果你已经有了一个Iterable
,你可以从它的spliterator()
方法中得到一个Spliterator
(虽然你可能想写一个更好的一个;默认是弱的)。
如果您有一个Iterator
,您可以使用Spliterators.spliteratorUnknownSize(Iterator)
将它变成一个Spliterator
。 (同样,这会为您提供一个拆分器,但不一定是最佳拆分器。)
如果你两者都没有,你可以写一个Spliterator
;它通常比编写 Iterator
更容易(实现更多方法,但通常更简单,因为您不必在 next
和 hasNext
之间重复逻辑.)
关于java - 从头开始或从迭代器创建流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26255940/