Introducing another type parameter that extends S is correct, however, to get the result as List<S> but not as List<T> , you must .map() records that pass the predicate type::isInstance to S
public static <T extends Foo, S extends T> List<S> getFromList(List<T> list, Class<S> type) { return list.stream() .filter(type::isInstance) .map(type::cast) .collect(Collectors.toList()); }
As suggested by @Eran , this can even be simplified to work with only one type parameter:
public static <T extends Foo> List<T> getFromList(List<Foo> list, Class<T> type) { return list.stream() .filter(type::isInstance) .map(type::cast) .collect(Collectors.toList()); }
source share