code: public int reduce(int identity, @NotNull IntBinaryOperator op) {
          int result = identity;
          while(iterator.hasNext()) {
              int value = iterator.nextInt();
              result = op.applyAsInt(result, value);
          }
          return result;
      }
docs: Performs a reduction on the elements of this stream, using the provided
  identity value and an associative accumulation function, and returns the
  reduced value.
  
  <p>The {@code identity} value must be an identity for the accumulator
  function. This means that for all {@code x},
  {@code accumulator.apply(identity, x)} is equal to {@code x}.
  The {@code accumulator} function must be an associative function.
  
  <p>This is a terminal operation.
  
  <p>Example:
  <pre>
  identity: 0
  accumulator: (a, b) -&gt; a + b
  stream: [1, 2, 3, 4, 5]
  result: 15
  </pre>
  
  @param identity the identity value for the accumulating function
  @param op an associative non-interfering stateless function for
  combining two values
  @return the result of the reduction
  @see #sum()
  @see #min()
  @see #max()