# Binary operator in reduce for parallel and unordered streams

Brian Goetz brian.goetz at oracle.com
Fri Mar 22 11:34:46 PDT 2013

```If the stream source is unordered, then the combining function also
needs to be commutative in order to get determinism.  We've not yet
worked the implications of ordering through the specs, so this doesn't
yet appear, but it will.

On 3/22/2013 2:17 PM, Georgiy Rakov wrote:
> Hello,
>
> let's consider following Stream method:
>
>      T reduce(T identity, BinaryOperator<T> reducer)
>
> According to some intuition I see that following constraints should be
> imposed on reducer depending on the stream type:
>
> - if stream is parallel provided encounter ordered is determined reducer
> must be /associative /(but /commutative /property is not required),
> otherwise the result, say, is not guaranteed to be deterministic; i.e.
> for any a, b and c check must always be true:
>
>
>      T r1 = reducer.apply(reducer.apply(a, b), c);
>
>      T r2 = reducer.apply(a, reducer.apply(b, c));
>      boolean check = r1.equals(r2);
>
> - if stream is unordered (encounter ordered isn't determined) reducer
> must be both /associative /and /commutative, /otherwise the result, say,
> is not guaranteed to be deterministic; i.e. for any a, b and c check
> must always be true:
>
>      T r1 = reducer.apply(reducer.apply(a, b), c);
>
>      T r2 = reducer.apply(a, reducer.apply(b, c));
>      boolean check1 = r1.equals(r2);
>
> and for any a and b check must always be true:
>
>      T r1 = reducer.apply(a, b);
>
>      T r2 = reducer.apply(b, a);
>      boolean check = r1.equals(r2);
>
> - for sequential stream reducer is required to have no constraints, i.e.
> result will be deterministic in any way (including that neither
> associative nor commutative property is required);
>
> I wonder whether this intuition is right and if it is whether spec will
> specify such constraints.
>
> BTW this intuition now contradicts in some way with spec which says that
> reducing function must always be _*/associative/*_/:/
>
>      /////////Perform a /reduction/ on the elements of this stream using
>      the provided identity value and an _*associative *_reducing
>      function, and return the reduced value/////////
>      //////////////////
>