如何实现Java流?

时间:2015-06-06 17:27:18

标签: java java-8 java-stream

我想实现Stream<T>

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

这可以避免吗?

更具体地说,我如何流式传输t1t2t3,例如:

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

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

5 个答案:

答案 0 :(得分:31)

JDK的Stream标准实现是内部类java.util.stream.ReferencePipeline,您无法直接实例化它。

相反,您可以使用java.util.stream.Stream.builder()java.util.stream.StreamSupport.stream(Spliterator<T>, boolean)和各种 with1 其他静态工厂方法来创建默认实现的实例

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

此外,您还可以将流转换回分裂器,将它们包装在自定义分裂器中,然后如果您需要实现自己的有状态中间操作,则将它们转换回流 - 例如,由于标准API中的缺点 - 因为大多数可用的中间操作2
请参阅are not allowed to be stateful以获取示例。

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

答案 1 :(得分:10)

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

  AtomicInteger n = new AtomicInteger(0);
  Stream<Integer> stream = Stream.generate(() -> n.incrementAndGet()).limit(100);

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

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

答案 2 :(得分:8)

如果您想制作自己的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);
            }
        });

答案 3 :(得分:5)

其他人已经回答了如何提供通用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);
    }
}

答案 4 :(得分:5)

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

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

我发现这有点难以找到,因为您需要了解StreamSupport,Spliterators和Spliterator