如何按实例获取列表的所有元素?

mem*_*und 6 java generics collections java-8 java-stream

如何按实例获取列表的所有元素?

我有一个列表,可以有一个接口的任何类实现Foo:

interface Foo;
class Bar implements Foo;
Run Code Online (Sandbox Code Playgroud)

我想使用java8 streamapi提供一个实用工具方法来提取特定类类型的所有元素:

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());
}
Run Code Online (Sandbox Code Playgroud)

使用:

List<Foo> list;
List<Bar> bars = Util.getFromList(list, Bar.class);
Run Code Online (Sandbox Code Playgroud)

结果:它的工作原理,但我要补充@SuppressWarningsunchecked cast(List<T>).我怎么能避免这个?

Kon*_*kov 5

引入另一个扩展的类型参数S是正确的,但是,为了得到结果List<S>,而不是因为List<T>你必须.map()type::isInstance谓词传递给的条目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());
}
Run Code Online (Sandbox Code Playgroud)

正如@Eran建议的那样,这甚至可以简化为仅使用一个类型参数:

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());
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要引入另一个类型参数? (2认同)
  • 我在没有第二个参数的情况下测试了代码并且它有效(请参阅我的回答). (2认同)