我可以通过元素的 class 过滤 Stream<T> 并一步获得 Stream<U> 吗?

Can I filter a Stream<T> by element's class an get a Stream<U> in one step?

假设我有

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

我有一份动物清单 使用 Guava FluentIterable 我可以一步过滤和转换

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

使用Java8我需要做

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

滤镜&贴图不可能一步到位吧?

map步骤在运行时是不必要的(它什么都不做),你需要它只是为了绕过编译期间的类型检查。或者你可以使用脏的未经检查的转换:

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

遗憾的是,没有单步执行此操作的标准方法,但您可以使用第三方库。例如,在我的 StreamEx library there's a select method which solves this problem:

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