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