流式迭代器的最简单方法

Boh*_*ian 13 java iterator iterable java-8 java-stream

假设您想要流式迭代器的元素; 让我们使用一个具体的例子Scanner来实现Iterator<String>.

给出一个Iterator,说:

// Scanner implements Iterator<String>
Iterator<String> scanner = new Scanner(System.in);
Run Code Online (Sandbox Code Playgroud)

从中创建的选项Stream<String>很笨重:

StreamSupport.stream(
  Spliterators.spliteratorUnknownSize(scanner, Spliterator.ORDERED), false);
Run Code Online (Sandbox Code Playgroud)

或稍微简洁,但迟钝:

 StreamSupport.stream(
  ((Iterable<String>) () -> new Scanner(System.in)).spliterator(), false);
Run Code Online (Sandbox Code Playgroud)

在JDK中的某个地方是否有一个返回Stream<T>给定的工厂方法Iterator<T>

Ste*_*e K 10

我会简单地使用Stream.generate(iterator::next).是的,这是一个无限的流,但扫描仪也是如此System.in,除非你知道你要求多少行,在这种情况下它很容易使用

Stream.generate(iterator::next).limit(numLines);
Run Code Online (Sandbox Code Playgroud)

这可以防止迭代器必须迭代两次(一次作为迭代器,一次作为流).

如果你需要一个大小的流而不知道它有多大,但是不想让你的代码混乱,只需创建一个显式采用的实用工具方法Iterable<T>:

public static <T> Stream<T> stream(Iterable<T> it){
    return StreamSupport.stream(it.spliterator(), false);
}  
Run Code Online (Sandbox Code Playgroud)

它最终比在一条线上塞满所有东西更容易辨认,然后你可以打电话stream(()->iterator);stream(()->new Scanner(System.in));

您也可以轻松添加第二种便捷方法:

public static <T> Stream<T> stream(Iterator<T> it){
    return stream(()->it);
}
Run Code Online (Sandbox Code Playgroud)

让你打电话stream(iterator);stream(new Scanner(System.in));

虽然,如果我要阅读System.in流,我可能会使用Reader而不是扫描仪:

return new BufferedReader(new InputStreamReader(System.in)).lines();
Run Code Online (Sandbox Code Playgroud)