@Override
 public int reduce(int identity, IntBinaryOperator op) {
   return performOperation(
       TerminalFunctions.reduceFunction(identity, op),
       true,
       (i1, i2) -> op.applyAsInt(i1, i2),
       null);
 }
 @Override
 public void forEach(IntConsumer action) {
   if (!rehashAware) {
     performOperation(TerminalFunctions.forEachFunction(action), false, (v1, v2) -> null, null);
   } else {
     performRehashForEach(action);
   }
 }
 @Override
 public IntSummaryStatistics summaryStatistics() {
   return performOperation(
       TerminalFunctions.summaryStatisticsIntFunction(),
       true,
       (is1, is2) -> {
         is1.combine(is2);
         return is1;
       },
       null);
 }
 @Override
 public <R> R collect(
     Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
   return performOperation(
       TerminalFunctions.collectFunction(supplier, accumulator, combiner),
       true,
       (e1, e2) -> {
         combiner.accept(e1, e2);
         return e1;
       },
       null);
 }
 @Override
 public int[] toArray() {
   return performOperation(
       TerminalFunctions.toArrayIntFunction(),
       false,
       (v1, v2) -> {
         int[] array = Arrays.copyOf(v1, v1.length + v2.length);
         System.arraycopy(v2, 0, array, v1.length, v2.length);
         return array;
       },
       null,
       false);
 }
 @Override
 public OptionalDouble average() {
   long[] results =
       performOperation(
           TerminalFunctions.averageIntFunction(),
           true,
           (a1, a2) -> {
             a1[0] += a2[0];
             a1[1] += a2[1];
             return a1;
           },
           null);
   if (results[1] > 0) {
     return OptionalDouble.of((double) results[0] / results[1]);
   } else {
     return OptionalDouble.empty();
   }
 }
 @Override
 public OptionalInt findAny() {
   Integer result =
       performOperation(
           TerminalFunctions.findAnyIntFunction(),
           false,
           (i1, i2) -> {
             if (i1 != null) {
               return i1;
             } else {
               return i2;
             }
           },
           a -> a != null);
   if (result != null) {
     return OptionalInt.of(result);
   } else {
     return OptionalInt.empty();
   }
 }
 @Override
 public OptionalInt max() {
   Integer value =
       performOperation(
           TerminalFunctions.maxIntFunction(),
           false,
           (i1, i2) -> {
             if (i1 != null) {
               if (i2 != null) {
                 return i1 > i2 ? i1 : i2;
               }
               return i1;
             }
             return i2;
           },
           null);
   if (value == null) {
     return OptionalInt.empty();
   } else {
     return OptionalInt.of(value);
   }
 }
 @Override
 public OptionalInt reduce(IntBinaryOperator op) {
   Integer result =
       performOperation(
           TerminalFunctions.reduceFunction(op),
           true,
           (i1, i2) -> {
             if (i1 != null) {
               if (i2 != null) {
                 return op.applyAsInt(i1, i2);
               }
               return i1;
             }
             return i2;
           },
           null);
   if (result == null) {
     return OptionalInt.empty();
   } else {
     return OptionalInt.of(result);
   }
 }
 @Override
 public long count() {
   return performOperation(TerminalFunctions.countIntFunction(), true, (i1, i2) -> i1 + i2, null);
 }
 @Override
 public boolean noneMatch(IntPredicate predicate) {
   return performOperation(
       TerminalFunctions.noneMatchFunction(predicate), false, Boolean::logicalAnd, b -> !b);
 }
 @Override
 public boolean anyMatch(IntPredicate predicate) {
   return performOperation(
       TerminalFunctions.anyMatchFunction(predicate), false, Boolean::logicalOr, b -> b);
 }
 @Override
 public int sum() {
   return performOperation(TerminalFunctions.sumIntFunction(), true, (i1, i2) -> i1 + i2, null);
 }