LexByte
LexByte

Reputation: 412

Int stream and collect

So I am having trouble understanding the principle of this supplier ,accumulator and combiner in the collect from IntStream. I found an example.

IntStream.range(6,11)
         .collect(StringBuilder::new, 
                  StringBuilder::appendCodePoint,
                  StringBuilder::append);

Anyone mind explaining the StringBuilder::appendCodePoint part?

Upvotes: 5

Views: 999

Answers (2)

syntagma
syntagma

Reputation: 24354

Let's wrap this stream to make byte[] out of it and then String from the resulting array:

Arrays.toString(IntStream.range(6,11).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString().getBytes())

That would give us:

[6, 7, 8, 9, 10]

How does the collect work?

It takes the stream of 6..10 and collects it in the following order:

  1. It builds a new StringBuilder instance
  2. It accumulates, that is appends Unicode code point using StringBuilder::appendCodePoint to an accumulator. (equivalent to: (StringBuilder sb, int x) -> sb.appendCodePoint(x))
  3. It combines, that is adds the result of (2) to to the StringBuilder instance created in (1). (equivalent to: (StringBuilder sb1, StringBuilder sb2) -> sb1.append(sb2))

The type signature of this parametrized collect() call looks like this:

collect(Supplier<StrinBuilder> supplier,
                  ObjIntConsumer<StrinBuilder> accumulator,
                  BiConsumer<StrinBuilder, StrinBuilder> combiner);

Upvotes: 7

Eugene
Eugene

Reputation: 121088

What if we write it like this:

IntStream.range(6, 11)
          .collect(StringBuilder::new, 
             (StringBuilder sb, int x) -> sb.appendCodePoint(x),  
             StringBuilder::append);

The accumulator is a Consumer, that takes an Integer as argument and returns nothing.

StringBuilder::appendCodePoint is a method reference that does the same thing as the lambda expression.

Upvotes: 4

Related Questions