繁体   English   中英

Java - 返回指定泛型类型的列表

[英]Java - Return list of specified generic type

我有一个包含各种子类型的对象列表:

List<Dog> dogList = new ArrayList<>();
dogList.add(new Poodle())
dogList.add(new Dalmation());

我想搜索此列表并返回指定类的所有实例:

public <T extends Dog> List<T> getAll(Class<T> dogType){
    List<T> returnObjects = new ArrayList<>();
    for(T obj : dogList){
        if(dogType.instanceOf(obj){
            returnObjects.add(dogType.cast(obj));
        }
    }
    return returnObjects; 
}

用法:

List<Poodle> poodleList = getAll(Poodle.class); 

这是我对仿制药的第一次正确尝试,事情感觉他们有点失控。 这是一种体面的做事方式,还是我错过了一个更简单/明显的解决方案?

编辑 :更新为使用instanceOf()和cast()以避免未经检查的强制转换

由于您提到您使用的是Java 8,因此可以使用Stream API:

public static <T extends Dog> List<T> getAll(Class<T> dogType) {
    return dogList.stream()
                  .filter(dogType::isInstance)
                  .map(dogType::cast)
                  .collect(toList());
}

此方法将从dog列表中创建一个Stream ,通过仅保留给定类的实例,转换为给定类并最终将该Stream收集到List中来过滤它们。

使用isInstance意味着如果您使用Poodle.class调用该方法,那么将保留所有PoodlePoodle子类的Poodle 如果您只想保留Poodle ,您可以使用Class.equals(other)代替。

另外,还要注意使用cast方法,没有选中的警告(此方法已经处理了它),它是安全的,在这里做到这一点,因为我们之前过滤正确的元素:没有ClassCastException皆可抛。

您必须声明方法的返回类型,并检查类上的isAssignableFrom()

public <T extends Dog> List<T> getAll(Class<T> dogType){
  List<T> returnObjects = new ArrayList<>();

  for(Dog obj : dogList){ 
    if( dogType.isInstance(obj) ){ //as mentioned in the edit as well as the comments
        returnObjects.add(dogType.cast(obj));
    }
  }
  return returnObjects; 
}

那样调用List<Poodle> poodleList = getAll(Poodle.class); 应该只返回Poodle或子类的实例,而getAll(Dog.class)应该返回所有的狗。

几点说明:

  • 假设dogList只包含狗,你应该在这里使用Dog类型。 否则使用该数组/集合的泛型类型(当有疑问时它将是Object )。
  • isAssignableFrom()检查最左边的类是否与传递的类或超类型相同,即如果Poodle extends Dog ,则Dog.class.isAssignableFrom( Poodle.class )将成立。 如果你只是在完全匹配之后使用dogType.equals(obj.getClass())

编辑 :关于dogType.isAssignableFrom(obj.getClass())的简短说明:如果obj为null,这可能会导致NPE,因此您必须处理它。 另一方面,使用dogType.isInstance(obj)更容易阅读并且不会受到NPE的影响(因为dogType不应该为null)。 (参见@Tunaki的回答)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM