Method returning a List<T> with parameters List<S1>, List<S2>, where S1 and S2 extends T

Viewed 89

I have this method:

public static <T> List<T> flat(List<T>... lists){
    return Stream.of(lists)
        .filter(Objects::nonNull)
        .flatMap(List::stream)
        .collect(toList());
}

The idea is to flat a list of lists and return a list with the same type.

Suppose that A and B extends C. This does not work:

List<A> listOfA;
List<B> listOfB;
List<C> listOfC = flat(listOfA, listOfB);

Because List<A> is not a List<C>!

Anyone know how to write a flat method signature with generics that admits what I'm trying to do?

Thanks!

1 Answers

If A extends C, B extends C, then List<A> and List<B> are assignable to List<? extends C>.

So you can declare it this way:

public static <T> List<T> flat(List<? extends T>... lists)

Test:

public static void main(String[] args) {
    List<String> listOfString = List.of("sss"); // String extends from Object
    List<Integer> listOfInt = List.of(1); // Integer extends from Object
    List<Object> list = flat(listOfString, listOfInt);
    System.out.println(list); // [sss, 1]
}
Related