2

In jdk8,the Stream provide collect function with supplier,accumulator and combiner

<R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);

I see the example in the annotation that transform a String Stream to a String,but I am very confused what the use of combiner in the function signature. I think in the accumulator,the new element has been added to the result continer?

I have tried give the combiner a null value,but I got a null pointer exception.

 Stream<String> stringStream = Stream.of("hello", "world", "morning");
 String string = stringStream.collect(StringBuilder::new, 
 StringBuilder::append, StringBuilder::append).toString();
 System.out.println(string);
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
Destinage
  • 133
  • 1
  • 5
  • 1
    seems similar to https://stackoverflow.com/questions/29959795/how-does-combiner-in-stream-collect-method-work-in-java-8 – Amin Heydari Alashti Jul 14 '19 at 03:10
  • `supplier + accumulator` is mandatory for sequential collecting. `combiner` is for parallel collecting. It's optional for sequential stream. If you don't want to provide it, you can throw a RuntimeException like `(a,b)->{throw new RuntimeException();}`. You cannot throw a regular unchecked exception. You cannot set it to null (which is puzzling for me as well) – SwiftMango Jul 14 '19 at 03:59
  • Javadoc explains a bit why you receive a NPE, the goal is that collect can be interchangeable between sequential and parallel stream without problem `

    Like {@link #reduce(Object, BinaryOperator)}, {@code collect} operations * can be parallelized without requiring additional synchronization.`

    – Yassin Hajaj Jul 14 '19 at 08:09

1 Answers1

3

Combiner : Combiner works in parallel processing, to combine the two values compatible with accumulator

collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)

supplier : It creates a new result container which will be populated by accumulator and combiner and finally it will be returned by collect() method. In parallel processing the Supplier function will be called multiple times that will return fresh value each time.

accumulator : It incorporates additional element into the result.

combiner : It combines two values that must be compatible with accumulator. Combiner works in parallel processing.

List<String> list = Arrays.asList("Mukesh", "Vishal", "Amar");
    String result = list.parallelStream().collect(StringBuilder::new,
            (response, element) -> response.append(" ").append(element),
            (response1, response2) -> response1.append(",").append(response2.toString()))
            .toString();
    System.out.println("Result: " + result);

Output :

Result:  Mukesh, Vishal, Amar 

If we use list.stream() then the output will be different because it is not parallel processing and so nothing to combine.

Output :

Result:  Mukesh Vishal Amar 
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98