code: public static <A, B, C, R> Stream<R> zip(final Iterator<? extends A> a, final Iterator<? extends B> b, final Iterator<? extends C> c, final A valueForNoneA,
              final B valueForNoneB, final C valueForNoneC, final TriFunction<? super A, ? super B, ? super C, R> zipFunction) {
          return new IteratorStream<>(new ObjIteratorEx<R>() {
              @Override
              public boolean hasNext() {
                  return a.hasNext() || b.hasNext() || c.hasNext();
              }
  
              @Override
              public R next() {
                  if (hasNext() == false) {
                      throw new NoSuchElementException();
                  }
  
                  return zipFunction.apply(a.hasNext() ? a.next() : valueForNoneA, b.hasNext() ? b.next() : valueForNoneB,
                          c.hasNext() ? c.next() : valueForNoneC);
              }
          });
      }
docs: Zip together the "a", "b" and "c" iterators until all of them runs out of values.
  Each triple of values is combined into a single value using the supplied zipFunction function.
  
  @param a
  @param b
  @param c
  @param valueForNoneA value to fill if "a" runs out of values.
  @param valueForNoneB value to fill if "b" runs out of values.
  @param valueForNoneC value to fill if "c" runs out of values.
  @param zipFunction
  @return