流化迭代器的最简单方法



假设你想要流化迭代器的元素;让我们使用Scanner的具体示例,它实现了Iterator<String>

给定一个Iterator,说:

// Scanner implements Iterator<String>
Iterator<String> scanner = new Scanner(System.in);

从它创建Stream<String>的选项很笨拙:

StreamSupport.stream(
  Spliterators.spliteratorUnknownSize(scanner, Spliterator.ORDERED), false);

或者更简洁但更钝的:

 StreamSupport.stream(
  ((Iterable<String>) () -> new Scanner(System.in)).spliterator(), false);

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

我只使用Stream.generate(iterator::next)。是的,它是一个无限流,但System.in的扫描器也是,除非你知道你要请求多少行,在这种情况下,使用

很容易
Stream.generate(iterator::next).limit(numLines);

这样可以避免迭代器必须迭代两次(一次作为迭代器,一次作为流)。

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

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

它最终比试图将所有内容塞进一行更容易读懂,并且然后你可以调用stream(()->iterator);stream(()->new Scanner(System.in));

您也可以很容易地添加第二个方便方法:

public static <T> Stream<T> stream(Iterator<T> it){
    return stream(()->it);
}

允许您调用stream(iterator);stream(new Scanner(System.in));

虽然,如果我要将System.in读取到流中,我可能会使用Reader而不是Scanner:

return new BufferedReader(new InputStreamReader(System.in)).lines();

最新更新