Can I filter Stream <T> by element class and get Stream <U> in one step?

Say I have

class Dog extends Animal {} class Cat extends Animal {} 

And I have a list of animals Using Guava FluentIterable I can filter and convert in one step

 List<Cat> cats = FluentIterable.from(animals) .filter(Cat.class) .toList(); 

Using Java8 I need to do

 List<Cat> cats = animals.stream() .filter(c -> c instanceof Cat) .map(c -> (Cat) c) .collect(Collectors.toList()); 

It’s not possible to make a filter and a map in one step, right?

+6
source share
1 answer

The map step is not needed at runtime (it just doesn’t do anything), you just need to bypass type checking at compile time. Alternatively, you can use the dirty untested cast:

 List<Cat> cats = ((Stream<Cat>) (Stream<?>) animals.stream().filter( c -> c instanceof Cat)).collect(Collectors.toList()); 

Unfortunately, there is no standard way to do this in one step, but you can use third-party libraries. For example, in my StreamEx library StreamEx there is a select method that solves this problem :

 List<Cat> cats = StreamEx.of(animals).select(Cat.class).toList(); 
+3
source

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


All Articles