code: public <U> StreamEx<U> intervalMap(BiPredicate<? super T, ? super T> sameInterval,
              BiFunction<? super T, ? super T, ? extends U> mapper) {
          return collapseInternal(sameInterval, PairBox::single, (box, t) -> {
              box.b = t;
              return box;
          }, (left, right) -> {
              left.b = right.b;
              return left;
          }).map(pair -> mapper.apply(pair.a, pair.b));
      }
docs: Returns a stream consisting of results of applying the given function to
  the intervals created from the source elements.
  
  <p>
  This is a <a href="package-summary.html#StreamOps">quasi-intermediate</a>
  partial reduction operation. This operation is the same as
  {@code groupRuns(sameInterval).map(list -> mapper.apply(list.get(0), list.get(list.size()-1)))}
  , but has less overhead as only first and last elements of each interval
  are tracked.
  
  @param <U> the type of the resulting elements
  @param sameInterval a non-interfering, stateless predicate to apply to
  the pair of adjacent elements which returns true for elements
  which belong to the same interval.
  @param mapper a non-interfering, stateless function to apply to the
  interval borders and produce the resulting element. If value was
  not merged to the interval, then mapper will receive the same
  value twice, otherwise it will receive the leftmost and the
  rightmost values which were merged to the interval. Intermediate
  interval elements are not available to the mapper. If they are
  important, consider using {@link #groupRuns(BiPredicate)} and map
  afterwards.
  @return the new stream
  @see #collapse(BiPredicate, BinaryOperator)
  @see #groupRuns(BiPredicate)
  @since 0.3.3