Hello!

There's a Stream.builder for this purpose:

var builder = Stream.<String>builder();
new Parser("1 2 3").parse(builder);
builder.build().forEach(System.out::println);

A little bit more verbose than your suggestion but this way it's more
clear that the whole stream content will be buffered.

With best regards,
Tagir Valeev

On Sun, May 22, 2022 at 5:54 AM Remi Forax <fo...@univ-mlv.fr> wrote:
>
> Hi all,
> a stream is kind of push iterator so it can be created from any object that 
> has a method like forEach(Consumer),
> but sadly there is no static method to create a Stream from a Consumer of 
> Consumer so people usually miss that creating a Stream from events pushed to 
> a consumer is easy.
>
> By example, let say i've a very simple parser like this, it calls the 
> listener/callback for each tokens
>
>   record Parser(String text) {
>     void parse(Consumer<? super String> listener) {
>       for(var token: text.split(" ")) {
>          listener.accept(token);
>       }
>     }
>   }
>
> Using the method Stream.fromForEach, we can create a Stream from the sequence 
> of tokens that are pushed through the listener
>   var parser = new Parser("1 2");
>   var stream = Stream.fromForEach(parser::parse);
>
> It can also works with an iterable, an optional or even a collection
>   Iterable<String> iterable = ...
>   var stream = Stream.fromForEach(iterable::forEachRemaning);
>
>   Optional<String> optional = ...
>   var stream = Stream.fromForEach(optional::ifPresent);
>
>   List<String> list = ...
>   var stream = Stream.fromForEach(list::forEach);
>
> I known the last two examples already have their own method stream(), it's 
> just to explain how Stream.fromForEach is supposed to work.
>
> In term of implementation, Stream.fromForEach() is equivalent to creating a 
> stream using a mapMulti(), so it can be implemented like this
>
>   static <T> Stream<T> fromForEach(Consumer<? super Consumer<T>> forEach) {
>     return Stream.of((T) null).mapMulti((__, consumer) -> 
> forEach.accept(consumer));
>   }
>
> but i think that Stream.fromForEach(iterable::forEachRemaning) is more 
> readable than Stream.of(iterable).mapMult(Iterable::forEachRemaining).
>
> The name fromForEach is not great and i'm sure someone will come with a 
> better one.
>
> regards,
> RĂ©mi

Reply via email to