类型不匹配:无法转换为Map <string,list <animal>&gt;映射<string,list <dog>&gt;

时间:2015-09-21 17:19:59

标签: java generics casting polymorphism maps

我在解决泛型问题时遇到了一些麻烦。我有一个&#34; Cat&#34;对象和&#34; Dog&#34;我需要传递给同一方法的对象。该方法的返回类型是&#34; String&#34;的映射。和动物名单&#34;动物名单&#34;我试图找出一种方法将地图与动物列表转换为带有猫或狗列表的地图。

如果我有一个单独的Cats and 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);

    }

}

注意:这是一个简化的例子,我必须能够使用地图中的列表作为&#34; Cat&#34;或&#34;狗&#34;对象。

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");
    }

}


{{1}}

Dog类与Cat相同,但使用doCatStuff方法。

提前谢谢。

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

您将方法声明为返回Map<String, List<Animal>>。此类型与Map<String, List<Dog>>不兼容,因为List<Animal>List<Dog>不兼容。这些不兼容,因为第一个声明List<Animal>不允许Animal的任何子类型。其次,虽然所有Dog都是Animal s,但并非所有Animal都是Dog s。

对于这种情况,您需要的是占位符。

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

答案 2 :(得分:0)

List<Cat>List<Dog>更改为List<Animal>

也许这会有所帮助:https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html