I'm streaming objects of a class implementing an interface. I'd like to collect them as a list of elements of the interface, rather than the implementing class.
This seems impossible with Java 16.0.1's Stream#toList
method. For example in the code below, the last statement will fail to compile.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class WhyDodo {
private interface Dodo { }
private static class FancyDodo implements Dodo { }
public static void main(String[] args) {
final List<Dodo> dodos = Stream.of(new FancyDodo()).collect(Collectors.toList());
final List<FancyDodo> fancyDodos = Stream.of(new FancyDodo()).toList();
final List<Dodo> noFancyDodos = Stream.of(new FancyDodo()).toList();
}
}
We could explicitly cast each element from FancyDodo
to Dodo
. But at least for brevity, we could just as well use .collect(Collectors.toList())
.
Why can't I use Stream#toList to collect a list of a class' interface in Java 16?
And if anyone has a better solution than explicitly casting, I'd be happy to hear as well :)
Stream.<Dodo>of(new FancyDodo())
. With that factory method, you getStream<FancyDodo>
, which is not compatible withStream<Dodo>
– Magnetic.collect(Collectors.toList())
unless the documentation could call that out. Another interesting line isfinal List<Dodo> fancyDodosAgain = Arrays.asList(Stream.of(new FancyDodo()).toArray(Dodo[]::new))
– OlszewskiList<T>
, whereT
is whatever it is a stream of. If you want a more abstract type, that's easy:List<Dodo> dodos = fancyDodos.stream().map(d -> (Dodo) d).toList()
– DisplayedList<? extends Dodo> = fancyDodos.stream().toList()
, since aList<FancyDodo>
is aList<? extends Dodo>
. – Displayed<U super T> List<U> toList()
). This syntax does not exist because when Generics were introduced, the creators thought that this was rarely needed. It works withcollect
, because thetoList
collector introduces its own type variable which gets mapped to the Stream’s type parameter with asuper
bound at thecollect
call. Edit: oh, just saw this comment… – Ragan