如何实现Java流?

cla*_*l3r 26 java java-8 java-stream

我想实现一个Stream<T>.

我不想只使用implements Stream<T>,因为我必须实施大量的方法.

这可以避免吗?

更具体的,我怎么能流t1,t2以及t3例如:

class Foo<T> {
    T t1, t2, t3;

    Foo(T t1, T t2, T t3) {
        this.t1 = t1;
        this.t2 = t2;
        this.t3 = t3;
    }
}
Run Code Online (Sandbox Code Playgroud)

the*_*472 35

JDK的标准实现Stream是内部类java.util.stream.ReferencePipeline,不能直接实例化它.

相反,你可以使用java.util.stream.Stream.builder(),java.util.stream.StreamSupport.stream(Spliterator<T>, boolean)以及各种1,2等静态工厂方法来创建默认实现的实例.

使用spliterator可能是最强大的方法,因为它允许您懒惰地提供对象,同时如果您的源可以分成多个块,还可以实现高效的并行化.

此外,您还可以将流转换回拆分器,将它们包装在自定义拆分器中,然后将它们转换回流,如果您需要实现自己的有状态中间操作 - 例如由于标准API中的缺点 - 因为大多数可用的中间操作都是不允许有状态.
请参阅此SO答案以获取示例.

原则上,您可以编写自己的流接口实现,但这将非常繁琐.


Ita*_*man 11

您通常不需要编写自己的流类.相反,您可以通过现有方法创建流.例如,以下是如何创建值为1,100的流:

  AtomicInteger n = new AtomicInteger(0);
  Stream<Integer> stream = Stream.generate(() -> n.incrementAndGet()).limit(100);
Run Code Online (Sandbox Code Playgroud)

所以在这里我们创建了一个无限的整数流:1,2,3,....然后我们limit(100)在那个无限流上使用它来获取100个元素的流.

为清楚起见,如果您想要一个整数流(以固定间隔),您应该使用IntStream.range().这只是一个示例,用于显示如何使用定义流Stream.generate(),从而为您提供更大的灵活性,因为它允许您使用任意逻辑来确定蒸汽元素.

  • 在这种情况下,`IntStream.range(0,100)`会更有效率. (2认同)

Ali*_*ell 11

如果您想制作自己的Stream,因为您需要自定义close()逻辑,最简单的解决方案是从Iterator创建一个Stream,然后调用onClose(Runnable).例如,通过杰克逊从阅读器流式传输:

MappingIterator<?> values = objectMapper.reader(type).readValues(reader);
return StreamSupport
        .stream(Spliterators.spliteratorUnknownSize(values, Spliterator.ORDERED), false)
        .onClose(() -> {
            try {
                reader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
Run Code Online (Sandbox Code Playgroud)


Rob*_*rtG 7

为了完整起见,我在SO的答案中没有直接找到它:如果要将现有的Iterator转换为Stream(例如,因为要连续生成元素),请使用以下命令:

StreamSupport.stream(
    Spliterators.spliterator(myIterator, /* initial size*/ 0L, Spliterator.NONNULL), 
    /* not parallel */ false);
Run Code Online (Sandbox Code Playgroud)

我发现很难找到它,因为您需要了解StreamSupport,Spliterators和Spliterator


Luk*_*der 6

其他人已经回答了如何提供通用Stream实现.关于您的具体要求,请执行以下操作:

class Foo<T> {

    T t1, t2, t3;

    Foo(T t1, T t2, T t3) {
        this.t1 = t1;
        this.t2 = t2;
        this.t3 = t3;
    }

    Stream<T> stream() {
        return Stream.of(t1, t2, t3);
    }
}
Run Code Online (Sandbox Code Playgroud)