Finite generated Stream in Java - how to create one?

后端 未结 2 1846
抹茶落季
抹茶落季 2020-12-24 10:44

In Java, one can easily generate an infinite stream with Stream.generate(supplier). However, I would need to generate a stream that will eventually finish.

相关标签:
2条回答
  • 2020-12-24 11:22

    Is there any reasonable easy way to do this in Java, without implementing the entire Stream interface on my own?

    A simple .limit() guarantees that it will terminate. But that's not always powerful enough.

    After the Stream factory methods the simplest approach for creating customs stream sources without reimplementing the stream processing pipeline is subclassing java.util.Spliterators.AbstractSpliterator<T> and passing it to java.util.stream.StreamSupport.stream(Supplier<? extends Spliterator<T>>, int, boolean)

    If you're intending to use parallel streams note that AbstractSpliterator only yields suboptimal splitting. If you have more control over your source fully implementing the Spliterator interface can better.

    For example, the following snippet would create a Stream providing an infinite sequence 1,2,3...

    in that particular example you could use IntStream.range()

    But the stream will obviously finish at some point, and terminal operators like (collect() or findAny()) need to work on it.

    short-circuiting operations like findAny() can actually finish on an infinite stream, as long as there is any element that matches.

    Java 9 introduces Stream.iterate to generate finite streams for some simple cases.

    0 讨论(0)
  • 2020-12-24 11:31

    Kotlin code to create Stream of JsonNode from InputStream

    
        private fun InputStream.toJsonNodeStream(): Stream<JsonNode> {
            return StreamSupport.stream(
                    Spliterators.spliteratorUnknownSize(this.toJsonNodeIterator(), Spliterator.ORDERED),
                    false
            )
        }
    
        private fun InputStream.toJsonNodeIterator(): Iterator<JsonNode> {
            val jsonParser = objectMapper.factory.createParser(this)
    
            return object: Iterator<JsonNode> {
    
                override fun hasNext(): Boolean {
                    var token = jsonParser.nextToken()
                    while (token != null) {
                        if (token == JsonToken.START_OBJECT) {
                            return true
                        }
                        token = jsonParser.nextToken()
                    }
                    return false
                }
    
                override fun next(): JsonNode {
                    return jsonParser.readValueAsTree()
                }
            }
        }
    
    
    0 讨论(0)
提交回复
热议问题