Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通用列表的映射不能很好地转换_Java_Generics - Fatal编程技术网

Java 通用列表的映射不能很好地转换

Java 通用列表的映射不能很好地转换,java,generics,Java,Generics,我不想用语言来表达,我只举一个例子: 我有一个动物类,还有一条狗、鱼、猫等,它们扩展了动物的范围 我有三种不同的方法,返回Map,Map,Map。我们将这些称为getDogMap、getCatMap和getFishMap 我正在编写一个通用方法,它根据各种参数调用其中一个方法。以下是我希望被允许做的事情: public void <A extends Animal> doSomething(){ Map<String,List<A>> someMap

我不想用语言来表达,我只举一个例子:

我有一个动物类,还有一条狗、鱼、猫等,它们扩展了动物的范围

我有三种不同的方法,返回Map,Map,Map。我们将这些称为getDogMap、getCatMap和getFishMap

我正在编写一个通用方法,它根据各种参数调用其中一个方法。以下是我希望被允许做的事情:

public void <A extends Animal> doSomething(){

    Map<String,List<A>> someMap;

    if(someCondition){
        someMap = getDogMap();
    }else if(anotherCondition){
        someMap = getFishMap();
    }else{
        someMap = getCatMap():
    }
}
或者至少,通过使用someMap=Map getDogMap

然而,这是行不通的。Eclipse告诉我类型不匹配:无法从映射转换到映射如果我尝试强制转换,它告诉我无法从映射转换到映射

我做错了什么?

public void并不意味着A是扩展动物的任何类型,它意味着A是扩展动物的特定类型之一。您需要使用以下声明:

public void doSomething() {
    Map<String, ? extends List<? extends Animal>>  someMap;
    // ...
}
同样,对于您的地图:

public void并不意味着A是扩展Animal的任何类型,它意味着A是扩展Animal的特定类型之一。您需要使用以下声明:

public void doSomething() {
    Map<String, ? extends List<? extends Animal>>  someMap;
    // ...
}
同样,对于您的地图:


这里的问题在于泛型类型的工作方式

在Java中,您可能认为数字是整数的超类,您是对的。您还希望Number[]是Integer[]的超类。你也是对的。但是,不能说List是List的超类。这违反了类型安全性

List<Integer> intList = new ArrayList<Integer>();
List<Number> numList = intList; // the system stops you here
numList.add(Math.PI); // so that you don't do this

这里的问题在于泛型类型的工作方式

在Java中,您可能认为数字是整数的超类,您是对的。您还希望Number[]是Integer[]的超类。你也是对的。但是,不能说List是List的超类。这违反了类型安全性

List<Integer> intList = new ArrayList<Integer>();
List<Number> numList = intList; // the system stops you here
numList.add(Math.PI); // so that you don't do this


映射某物映射@ant除了不会编译之外,您不能在声明中定义类型变量或类型变量的额外绑定。Map someMap@ant除了不会编译之外,您不能在声明中定义类型变量或类型变量的额外绑定。您是对的,但这就是我想要的功能。这是从字符串到一种动物列表的映射。这三种方法都返回了这个结果。另外,放在一边,使用三种方法都返回不同的动物亚型。因此,可以保存这些方法的返回值的单个变量必须能够保存动物的任何子类型。这不是问题。A可以是这些类型中的任何一种-除非您的原始代码没有正确表达此约束。我还修正了我现在实际编译的答案。一条经验法则:如果你的方法有一个类型参数,而该参数既没有在参数类型中使用,也没有在返回类型中使用,那么你很可能做得不对。方法类型参数仅用于表示参数/retval类型上/之间的约束,它们不会有意义地影响方法体中的局部变量。这是从字符串到一种动物列表的映射。这三种方法都返回了这个结果。另外,放在一边,使用三种方法都返回不同的动物亚型。因此,可以保存这些方法的返回值的单个变量必须能够保存动物的任何子类型。这不是问题。A可以是这些类型中的任何一种-除非您的原始代码没有正确表达此约束。我还修正了我现在实际编译的答案。一条经验法则:如果你的方法有一个类型参数,而该参数既没有在参数类型中使用,也没有在返回类型中使用,那么你很可能做得不对。方法类型参数仅用于表示参数/retval类型上/之间的约束,它们不会有意义地影响方法体中的局部变量。是的。谢谢你真正理解我的问题。现在-你有解决办法吗?!?或者我必须编写三个助手方法来对每个列表中的每个元素进行类型转换。您可以简单地将someMap声明为Map类型吗?这与您上面描述的原因不同。我不能从一个列表到另一个列表施放。哇。不知道我在想什么。给我一秒钟,我会想一些事情…一个答案是MapsomeMap或MapYES。谢谢你真正理解我的问题。现在-你有解决办法吗?!?或者我必须编写三个助手方法来对每个列表中的每个元素进行类型转换。您可以简单地将someMap声明为Map类型吗?这与您上面描述的原因不同。我不能从一个列表到另一个列表施放。哇。不知道我在想什么。给我一点时间,我会想点什么…一个答案是mapsomemap或Map
List<Animal> animals = new List<Animal>();
List<Dog> dogs = new List<Dog>();
animals.addAll(dogs);