Hello!

Still from the practical point of view it would be really helpful to
have instance methods like `Stream.append(T... elements)` and
`Stream.prepend(T... elements)` (default implementation may utilize
`concat`). Very often it's necessary to add one or two special
elements to the stream, and using the `concat` makes code very ugly.

C.f.:

list.stream().filter(...).map(...).append(specialElement).collect(toList());
v.s.:
Stream.concat(list.stream().filter(...).map(...),
Stream.of(specialElement)).collect(toList());

Currently I prefer this (unless I can use third-party libraries which
provide `append`):
List<T> result = list.stream().filter(...).map(...).collect(toList());
// toCollection(ArrayList::new) for purists
result.add(specialElement);

With best regards,
Tagir Valeev.
On Thu, Oct 11, 2018 at 11:11 PM Brian Goetz <brian.go...@oracle.com> wrote:
>
> It would surely be convenient; I've wished for this a few times. But,
> there's a reason for this choice, and its not just laziness;
> contravariant type variables have some pretty scary challenges. See, for
> example, this paper:
>
>      http://www.cis.upenn.edu/~bcpierce/papers/variance.pdf
>
> in which it is shown that contravariance is one of the ingredients in a
> witches brew that leads to undecideability of type checking.
>
>
>
> On 10/11/2018 12:06 AM, James Roper wrote:
> > With the work I'm doing at the moment at creating a Reactive Streams
> > equivalent to java.util.stream, I've often wondered why Stream.concat is a
> > static method, rather than an instance method concating the given stream
> > onto this. But I think the reason has just dawned on me, and I wanted to
> > confirm that I'm correct.
> >
> > Java doesn't support contravariant type variables - it does for type
> > declarations, but not type variables.
> >
> > To put more concretely, if I had a Stream<Integer>, and I wanted to concat
> > a Stream<Number>, this is a valid thing to do, the resulting stream would
> > be Stream<Number>. But doing that with an instance method would require
> > something like this:
> >
> > public <S super T> Stream<S> concat(Stream<? extends S> b);
> >
> > Which is not supported (specifically, <S super T> type variable declaration
> > is not supported). In contrast, what we have in the actual API:
> >
> > public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends
> > T> b);
> >
> > does allow me to concat a Stream<Integer> and Stream<Number> with a
> > resulting type of Stream<Number>.
> >
> > Is this right, or are there other reasons? Also, is there any possibility
> > that Java might support contravariance in type variables in future? My
> > reason for wanting it is to provide the following method for reactive
> > streams:
> >
> > public <S super T> Publisher<S> onErrorResumeWith(Function<? super
> > Throwable, ? extends Publisher<? extends S>> f);
> >
> > The intent of this method is when a stream encounters an error, the passed
> > function is invoked with the error, and that function returns a publisher
> > that gets concated to the current stream instead of the error being
> > emitted. This could possibly be implemented with a static method:
> >
> > public static <T> Publisher<T> onErrorResumeWith(Publisher<? extends T> a,
> > Function<? super Throwable, ? extends Publisher<? extends T> f);
> >
> > But unlike concat, this method feels and reads much better as an instance
> > method, as a static method it's a little confusing.
> >
> > Regards,
> >
> > James
> >
>

Reply via email to