Should Stream be covariant? (original) (raw)

Ali Lahijani alahijani at gmail.com
Wed Jan 30 12:36:15 PST 2013


Here is the code:

public class Covariance {

/**
 * Lemma: {@code Optional<T>} is covariant in {@code T}
 */
public static <T> Optional<T> elevate(final Optional<? extends T>

delegate) { return delegate.isPresent() ? Optional.of(delegate.get()) : Optional.empty(); }

/**
 * Lemma: {@code Iterator<T>} is covariant in {@code T}
 */
public static <T> Iterator<T> elevate(final Iterator<? extends T>

delegate) { return new Iterator() { @Override public boolean hasNext() { return delegate.hasNext(); }

        @Override
        public T next() {
            return delegate.next();
        }

        @Override
        public void remove() {
            delegate.remove();
        }
    };
}

/**
 * Lemma: {@code Spliterator<T>} is covariant in {@code T}
 */
public static <T> Spliterator<T> elevate(final Spliterator<? extends T>

delegate) { return new Spliterator() {

        public int getNaturalSplits() {
            return delegate.getNaturalSplits();
        }

        public Spliterator<T> split() {
            return elevate(delegate.split());
        }

        public Iterator<T> iterator() {
            return elevate(delegate.iterator());
        }

        public boolean isPredictableSplits() {
            return delegate.isPredictableSplits();
        }

        public void forEach(Block<? super T> block) {
            delegate.forEach(block);
        }

        public long getSizeIfKnown() {
            return delegate.getSizeIfKnown();
        }

        public long estimateSize() {
            return delegate.estimateSize();
        }
    };
}

/**
 * Theorem: {@code Stream<T>} is covariant in {@code T}
 */
public static <T> Stream<T> elevate(final Stream<? extends T> delegate)

{ return new Stream() { @Override public Stream filter(Predicate<? super T> predicate) { return elevate(delegate.filter(predicate)); }

        @Override
        public <R> Stream<R> map(Function<? super T, ? extends R>

mapper) { return delegate.map(mapper); }

        @Override
        public IntStream map(ToIntFunction<? super T> mapper) {
            return delegate.map(mapper);
        }

        @Override
        public LongStream map(ToLongFunction<? super T> mapper) {
            return delegate.map(mapper);
        }

        @Override
        public DoubleStream map(ToDoubleFunction<? super T> mapper) {
            return delegate.map(mapper);
        }

        @Override
        public <R> Stream<R> explode(BiConsumer<Downstream<R>, ? super

T> exploder) { return delegate.explode(exploder); }

        @Override
        public Stream<T> distinct() {
            return elevate(delegate.distinct());
        }

        @Override
        public Stream<T> sorted() {
            return elevate(delegate.sorted());
        }

        @Override
        public Stream<T> sorted(Comparator<? super T> comparator) {
            return elevate(delegate.sorted(comparator));
        }

        @Override
        public void forEach(Consumer<? super T> consumer) {
            delegate.forEach(consumer);
        }

        @Override
        public void forEachUntil(Consumer<? super T> consumer,

BooleanSupplier until) { delegate.forEachUntil(consumer, until); }

        @Override
        public Stream<T> peek(Consumer<? super T> consumer) {
            return elevate(delegate.peek(consumer));
        }

        @Override
        public Stream<T> limit(long maxSize) {
            return elevate(delegate.limit(maxSize));
        }

        @Override
        public Stream<T> substream(long startingOffset) {
            return elevate(delegate.substream(startingOffset));
        }

        @Override
        public Stream<T> substream(long startingOffset, long

endingOffset) { return elevate(delegate.substream(startingOffset, endingOffset)); }

        @Override
        protected Object[] toArray() {
            return delegate.toArray();
        }

        @Override
        public <A> A[] toArray(IntFunction<A[]> generator) {
            return delegate.toArray(generator);
        }

        @Override
        public T reduce(T identity, BinaryOperator<T> reducer) {
            /*
             * TODO this one does work, but the implementation is not

"mechanically generated" */ // return delegate.reduce(identity, reducer, reducer);

            return delegate.reduce(identity, reducer);
        }

        @Override
        public Optional<T> reduce(BinaryOperator<T> reducer) {
            /*
             * TODO there is no hope for this one
             */
            return delegate.reduce(reducer);
        }

        @Override
        public <U> U reduce(U identity, BiFunction<U, ? super T, U>

accumulator, BinaryOperator reducer) { return delegate.reduce(identity, accumulator, reducer); }

        @Override
        public <R> R collect(Supplier<R> resultFactory, BiConsumer<R, ?

super T> accumulator, BiConsumer<R, R> reducer) { return delegate.collect(resultFactory, accumulator, reducer); }

        @Override
        public <R> R collect(Collector<? super T, R> collector) {
            return delegate.collect(collector);
        }

        @Override
        public <R> R collectUnordered(Collector<? super T, R>

collector) { return delegate.collectUnordered(collector); }

        @Override
        protected Optional<T> max(Comparator<? super T> comparator) {
            return elevate(delegate.max(comparator));
        }

        @Override
        protected Optional<T> min(Comparator<? super T> comparator) {
            return elevate(delegate.min(comparator));
        }

        @Override
        public boolean anyMatch(Predicate<? super T> predicate) {
            return delegate.anyMatch(predicate);
        }

        @Override
        public boolean allMatch(Predicate<? super T> predicate) {
            return delegate.allMatch(predicate);
        }

        @Override
        public boolean noneMatch(Predicate<? super T> predicate) {
            return delegate.noneMatch(predicate);
        }

        @Override
        public Optional<T> findFirst() {
            return elevate(delegate.findFirst());
        }

        @Override
        public Optional<T> findAny() {
            return elevate(delegate.findAny());
        }

        @Override
        public Stream<T> sequential() {
            return elevate(delegate.sequential());
        }

        @Override
        public Stream<T> parallel() {
            return elevate(delegate.parallel());
        }

        @Override
        public Iterator<T> iterator() {
            return elevate(delegate.iterator());
        }

        @Override
        public Spliterator<T> spliterator() {
            return elevate(delegate.spliterator());
        }

        @Override
        public boolean isParallel() {
            return delegate.isParallel();
        }

        @Override
        public int getStreamFlags() {
            return delegate.getStreamFlags();
        }
    };
}

}



More information about the lambda-libs-spec-observers mailing list