How to get all list items by instance?

How to get all list items by instance?

I have a list that can have any implementation of the Foo interface class:

 interface Foo; class Bar implements Foo; 

I want to use java8 stream api to provide a utility method for retrieving all the elements of a specific type of a class:

 public static <T extends Foo> List<T> getFromList(List<Foo> list, Class<T> type) { return (List<T>) list.stream().filter(entry -> type.isInstance(entry)).collect(Collectors.toList()); } 

via:

 List<Foo> list; List<Bar> bars = Util.getFromList(list, Bar.class); 

Result: it works, but I have to add @SuppressWarnings due to unchecked cast from (List<T>) . How can i avoid this?

+6
source share
3 answers

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()); } 
+5
source

This seems to work without warning:

 public static <T extends Foo> List<T> getFromList(List<Foo> list, Class<T> type) { return list.stream() .filter(entry -> type.isInstance(entry)) .map(entry->type.cast(entry)) .collect(Collectors.toList()); } 

Tested with replacement number Replacing Foo and Integer:

 public static <T extends Number> List<T> getFromList(List<Number> list, Class<T> type) { return list.stream().filter(entry -> type.isInstance(entry)).map(entry->type.cast(entry)).collect(Collectors.toList()); } public static void main(String[] args) { List<Number> list = new ArrayList<>(); list.add(5); list.add(3.4); list.add(7); List<Integer> bars = getFromList(list, Integer.class); System.out.println(bars); } 

Output:

 [5, 7] 
+4
source

Since list and type not of the same type, but rather a relationship of inheritance hierarchy, you are likely to add another type argument similar to the following:

 public static <T extends Foo, S extends T> List<T> getFromList(List<T> list, Class<S> type) { return list.stream().filter(type::isInstance).collect(Collectors.toList()); } 
+1
source

Source: https://habr.com/ru/post/984419/


All Articles