如何实现 Java 流?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30685623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 09:59:21  来源:igfitidea点击:

How to implement a Java stream?

javajava-8java-stream

提问by clankill3r

I want to implement a Stream<T>.

我想实现一个Stream<T>.

I don't want to just use implements Stream<T>, because I would have to implement a ton of methods.

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

Can this be avoided?

这可以避免吗?

To be more concrete, how can I stream t1, t2and t3for example:

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

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

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

采纳答案by the8472

The JDK's standard implementation of Streamis the internal class java.util.stream.ReferencePipeline, you cannot instantiate it directly.

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

Instead you can use java.util.stream.Stream.builder(), java.util.stream.StreamSupport.stream(Spliterator<T>, boolean)and various1, 2other static factory methods to create an instance of the default implementation.

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

Using a spliterator is probably the most powerful approach as it allows you to provide objects lazily while also enabling efficient parallelization if your source can be divided into multiple chunks.

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

Additionally you can also convert streams back into spliterators, wrap them in a custom spliterator and then convert them back into a stream if you need to implement your own stateful intermediate operations- e.g. due to shortcomings in the standard APIs - since most available intermediate ops are not allowed to be stateful.
See this SO answerfor an example.

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

In principle you could write your own implementation of the stream interface, but that would be quite tedious.

原则上,您可以编写自己的流接口实现,但这会非常乏味。

回答by Itay Maman

You usually do not need to write your own stream class. Instead you can create stream by existing methods. For instance, here is how to create a stream of the value 1, 100:

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

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

so in here we created an infinite stream of integers: 1, 2, 3, .... then we used limit(100)on that infinite stream to get back a stream of 100 elements.

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

For clarity, if you want a stream of integers (at fixed intervals) you should use IntStream.range(). This is just an example to show how streams can be defined using Stream.generate()which gives you more flexibility as it allows you to use arbitrary logic for determining steam's elements.

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

回答by Lukas Eder

Others have answered how to provide a general-purpose Streamimplementation. Regarding your specificrequirement, just do this:

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

回答by Alice Purcell

If you're wanting to make your own Stream because you want custom close()logic, the simplest solution is to create a Stream from an Iterator, and call onClose(Runnable). For instance, to stream from a Reader via Hymanson:

如果您因为需要自定义close()逻辑而想要创建自己的 Stream ,那么最简单的解决方案是从 Iterator 创建一个 Stream,然后调用onClose(Runnable). 例如,要通过 Hymanson 从 Reader 流式传输:

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);
            }
        });

回答by RobertG

For the sake of completeness, as I did not find this directly among the answers here on SO: If you want to transform an existing Iterator into a Stream (e.g., because you want to generate elements successively), use this:

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

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

I found this a bit hard to find, as you need to know StreamSupport, Spliterators and Spliterator

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