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
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