如何在泛型集合中使用addAll?

5
为什么会发生这种情况?
List<Map<String, Object>> a, b;
a.addAll(b);

编译

但是

List<? extends Map<String, ?>> a, b;
a.addAll(b);

它不能编译。

如何使后者编译成功?


? extends Map<String, ?>替换为扩展Map<String, Object>的类型,因为在声明变量时需要给它们指定类型。如果没有指定类型,则需要像第一个示例中使用接口。 - LuigiEdlCarno
6个回答

2
假设 CustomHashMap 继承自HashMap,您可以按照以下方式初始化a:
List<CustomHashMap<String, String> list = new ArrayList<CustomHashMap<String, String>>();
List<? extends Map<String, ?>> a = list;

如果您能够向a添加条目......
a.add(new HashMap<String, String>());

如果你遇到这种奇怪的情况

CustomHashMap<String, String> map = list.get(0); // you would expect to get CustomHashMap object but you will get a HashMap object instead

换句话说,当你使用“? extends Map”时,你不知道你的Map的实际类型,你只知道它是Map的某个子类型。因此,你不能向List中添加任意对象,因为你需要确保添加的对象有一个超类型。但是由于Map的确切类型是未知的,所以你无法做到这一点。请注意保留HTML标签。

1
根据Java文档,您可以在这种情况下声明辅助方法(虽然不太美观但可行):
static <T extends List<K>, V, K extends Map<String, V>> void addAllHelper(T from, T to) {
        from.addAll(to);
}

1

您无法向通配符泛型列表中添加项目。第一个是可以编译的,因为它有一个定义的类型。

然而,您可能会找到一些适合您目的的超类,并将其用作泛型参数。

更新:

另请参阅通配符 (在 Oracle 文档中)


为什么这个也无法编译?`List> a;` `List> b;` `a.addAll(b);` - Pinch
1
这是因为您将项目添加到通配符泛型集合a中。 - DerMike
因为你试图在使用通配符定义的集合中添加元素,而在Java中是不被允许的。 - arjacsoh
@arjacsoh 注意,如果使用? super通配符定义,可以添加Collection。 - Prashant Bhate
当然,在Collection<? super T>中,只能添加类型为T的元素,但问题涉及到带有extends通配符。 - arjacsoh

-1

当您使用具体的泛型类型进行声明时,它会编译。如果您定义一个类:

public class AClass<T extends Map<String, ?>> {

    public List<T> dostuff() {

        List<T> lista = new ArrayList<T>();
        List<T> listb = new ArrayList<T>();

        lista.addAll(listb);
        return lista;
    }
}

使用通配符无法编译。


-1
你可以使用类似以下方法来实现:
private <S extends Map<String, ?>> void method(List<S> a, List<S> b){
    a.addAll(b);
}

-1
以下代码应该可以帮助您解释这个问题: List<? super Number> a 被称为输出参数 out,可用于更新 List<? extends Number> b 被称为输入参数 in,可用于读取
下面的注释行会导致编译错误,原因在注释中已经说明。
public static void main(String[] args) {
    List<Integer> intList = new ArrayList<>();
    List<Double> doubleList = new ArrayList<>();
    List<Number> numberList = new ArrayList<>();
    addAll(numberList, intList);
    addAll(numberList, doubleList);
    addAll(intList, doubleList);//cant add double to int
    addAll(doubleList,intList);//cant add int double
    addAll(intList, numberList);//cant add number to int
}

private static<T> void addAll(List<? super T> a, List<? extends T> b) {
    a.addAll(b);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接