2015-09-21 89 views
0

我在解決泛型問題時遇到了一些麻煩。我有一個「Cat」對象列表和一個「Dog」對象列表,我需要將它們傳遞給同一個方法。該方法的返回類型是一個「字符串」和「動物列表」的地圖我試圖找出一種方法來將地圖與動物列表轉換爲具有貓或狗列表的地圖。類型不匹配:無法從地圖<字符串,列表<Animal>>轉換爲地圖<字符串,列表<Dog>>

這工作正常,如果我有一個單獨的貓和狗的方法,但我正在尋找一個更靈活的解決方案。

線得到錯誤的標題:

catMap = PetStore.groupAnimalsByOwner(cats); 
dogMap = PetStore.groupAnimalsByOwner(dogs); 

注:這是一個簡單的例子,我必須能夠使用列出了地圖爲「貓」和「狗」的對象。

public class Start { 

    public static void main(String[] args) { 

     Cat cat1 = new Cat("Jerry", "cat1"); 
     Cat cat2 = new Cat("Jerry", "cat2"); 
     Cat cat3 = new Cat("Fred", "cat3"); 

     List<Cat> cats = new LinkedList<Cat>(); 
     cats.add(cat1); 
     cats.add(cat2); 
     cats.add(cat3); 

     Dog dog1 = new Dog("Frank", "dog1"); 
     Dog dog2 = new Dog("Jerry", "dog2"); 
     Dog dog3 = new Dog("Bob", "dog3"); 

     List<Dog> dogs = new LinkedList<Dog>(); 
     dogs.add(dog1); 
     dogs.add(dog2); 
     dogs.add(dog3); 

     Map<String, List<Dog>> dogMap = new HashMap<String, List<Dog>>(); 
     Map<String, List<Cat>> catMap = new HashMap<String, List<Cat>>(); 

     // catMap should have 2 key/value pairs - key "Jerry" with a list containing cat1 and cat2 
     // and a pair - key "Fred" with a list containing only cat3 
     catMap = PetStore.groupAnimalsByOwner(cats); 

     // dogMap should have 3 key/value pairs - key "Frank" with a list containing dog1 
     // key "Jerry" with a list containing dog2 
     // Key "Bob" with a list containing dog3 
     dogMap = PetStore.groupAnimalsByOwner(dogs); 

    } 

} 


public class PetStore { 

    //Grouping by owner 
    public static Map<String, List<Animal>> groupAnimalsByOwner(List<? extends Animal> animals) { 
     Map<String, List<Animal>> groupedMap = new HashMap<String, List<Animal>>(); 
     List<Animal> tempList = null; 

     for (Animal summary : animals) { 
      String consolidatedInvoiceId = summary.getOwner(); 
      tempList = groupedMap.get(consolidatedInvoiceId); 
      if (tempList == null) { 
       tempList = new LinkedList<Animal>(); 
      } 
      tempList.add(summary); 
      groupedMap.put(consolidatedInvoiceId, tempList); 
     } 

     return groupedMap; 
    } 
} 


public interface Animal { 

    public String getOwner(); 
} 


public class Cat implements Animal { 

    private String owner; 
    private String name; 

    public Cat(String owner, String name) { 
     this.owner = owner; 
     this.name = name; 
    } 


    @Override 
    public String getOwner() { 
     return owner; 
    } 

    public String getName() { 
     return name; 
    } 

    public void doCatStuff() { 
     System.out.println("Do cat stuff"); 
    } 

} 

狗類是一樣的貓,但用doCatStuff方法。

預先感謝您。

+0

看看類似的問題http://stackoverflow.com/questions/32604266/inheriting-arraylist-property-from-superclass-but-assigning-different-types-to-i –

回答

3

就像List<Dog> isn't a List<Animal>Map<String, List<Cat>>不是Map<String, List<Animal>>

讓您groupAnimalsByOwner方法一般,與Animal作爲上限,使T被推斷爲Cat(或Dog)。您需要在該方法的主體中將Animal替換爲T

public static <T extends Animal> Map<String, List<T>> 
     groupAnimalsByOwner(List<? extends T> animals) 
{ 
    Map<String, List<T>> groupedMap = new HashMap<String, List<T>>(); 
    List<T> tempList = null; 

    for (T summary : animals) { 
     String consolidatedInvoiceId = summary.getOwner(); 
     tempList = groupedMap.get(consolidatedInvoiceId); 
     if (tempList == null) { 
      tempList = new LinkedList<T>(); 
     } 
     tempList.add(summary); 
     groupedMap.put(consolidatedInvoiceId, tempList); 
    } 

    return groupedMap; 
} 
+0

謝謝,這解決了這個問題。 – Tim

1

你聲明的方法爲返回Map<String, List<Animal>>。此類型與Map<String, List<Dog>>不兼容,因爲List<Animal>List<Dog>不兼容。這些不兼容,因爲第一個聲明List<Animal>不允許任何亞型Animal。其次,儘管所有Dog都是Animals,但並非所有Animal都是Dogs。

對於這種情況,你需要的是一個佔位符。

public static <T extends Animal> Map<String, List<T>> groupAnimalsByOwner(List<T> animals) { 
相關問題