2

The following code output is 24 all the time.

public static void main(String[] args) throws InterruptedException {
    List<String> list = new ArrayList<String>();
    list.add("java");
    list.add("php");
    list.add("python");
    list.add("perl");
    list.add("c");
    list.add("lisp");
    list.add("c#");
    int s = list.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> 0);
    System.out.println(s);
    s = list.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> x - y);
    System.out.println(s);
    s = list.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> x * y);
    System.out.println(s);

}   

Question is why combiner is effecting my code.

Eugene
  • 117,005
  • 15
  • 201
  • 306
Hasnain Ali Bohra
  • 2,130
  • 2
  • 11
  • 25

2 Answers2

5

combiner is only used for parallel streams.

But there might be other problems with your code even if you add parallel. They all violate some rules... Specifically:

Additionally, the combiner function must be compatible with the accumulator function; for all u and t, the following must hold

 combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)

And your combiners violate this, so depending on the number of CPU's you have - you will get different results - which is obviously wrong.

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • can you explain more about **combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)** ?? – Hasnain Ali Bohra Jul 27 '17 at 09:19
  • @HasnainAliBohra https://stackoverflow.com/questions/45054372/what-do-the-stream-reduce-requirements-exactly-entail/45054892#45054892 – Eugene Jul 27 '17 at 09:20
  • Thanks i was having same doubt form the same OCJP book.Im asking about the sentence>>Means what is u and what the expression **combiner.apply(u, accumulator.apply(identity, t))** is – Hasnain Ali Bohra Jul 27 '17 at 09:30
  • @HasnainAliBohra `u` and `t` would be two random elements from the stream (*any two elements*); and the `accumulator` and `combiner` are the second and third parameter of your `reduce` – Eugene Jul 27 '17 at 09:42
  • thanks u deserve upvote. – Hasnain Ali Bohra Jul 27 '17 at 09:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/150281/discussion-between-hasnain-ali-bohra-and-eugene). – Hasnain Ali Bohra Jul 27 '17 at 09:53
2

combiner would affect the result if you reduce parallel Stream. For a sequential Stream there is no need to combine partial results.

For example, when I change stream() to parallelStream() in you code, I get:

0
6
2304

Of course, all the combiners you supplied are bad combiners. You should supply a combiner that doesn't affect the final result of reduce.

Eran
  • 387,369
  • 54
  • 702
  • 768