How to implement a Java stream?

后端 未结 5 881
悲哀的现实
悲哀的现实 2020-12-01 06:34

I want to implement a Stream.

I don\'t want to just use implements Stream, because I would have to implement a ton of met

相关标签:
5条回答
  • 2020-12-01 06:50

    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 Jackson:

    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);
                }
            });
    
    0 讨论(0)
  • 2020-12-01 06:53

    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:

      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.

    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.

    0 讨论(0)
  • 2020-12-01 06:59

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

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

    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 answer for an example.

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

    0 讨论(0)
  • 2020-12-01 07:00

    Others have answered how to provide a general-purpose Stream implementation. Regarding your specific requirement, just do this:

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-01 07:06

    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:

    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

    0 讨论(0)
提交回复
热议问题