[英]Why can't Java convert an ArrayList<TreeSet<Integer>> into a List<Set<Object>>?
I'm attempting to do something that seems rather simple: sum the sizes of a list of sets. 我试图做一些看似相当简单的事情:总结一组列表的大小。 Netbeans gives the following warning/error:
Netbeans给出以下警告/错误:
actual argument java.util.ArrayList<java.util.TreeSet<java.lang.Integer>> cannot be converted to java.util.List<java.util.Set<java.lang.Object>> by method invocation conversion
for the following two pieces of code: 对于以下两段代码:
/**
* Sums the sizes of all sets in a list. Note that while there will be
* no duplicate elements in a single set, "sister" sets may contain
* elements, so the value returned is **not** equal to the number of unique
* elements in all sets.
* @param list, a List of Sets
* @return the number of elements contained in all sets
*/
public static int sizeOfListOfSets(List<Set<Object>> list) {
int size = 0;
for (Set<Object> set : list) {
size += set.size();
}
return size;
}
and then calling it with the following: 然后使用以下内容调用它:
ArrayList<TreeSet<Integer>> testList = new ArrayList<TreeSet<Integer>>();
TreeSet<Integer> testSet;
int size = 0;
testSet = new TreeSet<Integer>();
testSet.add(new Integer(++size));
testSet.add(new Integer(++size));
testList.add(testSet);
testSet = new TreeSet<Integer>();
testSet.add(new Integer(++size));
testList.add(testSet);
int expResult = size;
int result = Helpers.sizeOfListOfSets(testList);
the last line gives the compilation error: 最后一行给出了编译错误:
error: method sizeOfListOfSets in class Helpers cannot be applied to given types;
1 error
So, why can't java.lang.Integer be converted to java.lang.Object? 那么,为什么java.lang.Integer不能转换为java.lang.Object?
A List<Integer>
is not a List<Object>
. List<Integer>
不是List<Object>
。 If Java
allowed that, then you could call the method with List<String>
and you will be broken. 如果
Java
允许,那么您可以使用List<String>
调用该方法,您将被破坏。 As Jeremy Heiler
pointed out you can use List<? extends Object>
正如
Jeremy Heiler
指出你可以使用List<? extends Object>
List<? extends Object>
and you will be fine. List<? extends Object>
你会没事的。 This means every type which extends Object
is allowed. 这意味着允许扩展
Object
每个类型。 ?
is called a wildcard
in generic jargon. 在通用术语中称为
wildcard
。
Anything you declare as a generic type must be the exact same generic type always. 您声明为泛型类型的任何内容都必须始终是完全相同的泛型类型。 The only think that can vary is the base type ie:
可以改变的唯一想法是基本类型,即:
List<MyObject> myList = new ArrayList<MyObject>;
This is because for example if you had a parameter declared as List<Object>
, and you could pass it a List<Integer>
, then you would be able to add ANY kind of object to that list, which would break the type safety. 这是因为,例如,如果您有一个声明为
List<Object>
的参数,并且您可以将它传递给List<Integer>
,那么您将能够向该列表添加任何类型的对象,这将破坏类型安全性。
Although there is a workaround using the wildcard ?
虽然使用通配符有解决方法
?
, you still will NOT be able to add elements unless you do it like this <? super MyObject>
,你仍然无法添加元素,除非你这样做
<? super MyObject>
<? super MyObject>
, because anything higher on the inheritance tree would be ok to add to the list. <? super MyObject>
,因为继承树上任何更高的内容都可以添加到列表中。
The issue is not converting from an Integer to an Object, but from a list of Integer to a list of Object which fails because List<Integer>
is not a List<Object>
. 问题不是从Integer转换为Object,而是从Integer列表转换为Object列表失败,因为
List<Integer>
不是List<Object>
。 Java compiler does not try to automatically cast generic types. Java编译器不会尝试自动转换泛型类型。
You might change your method declaration to something like this to get away with the error: 您可以将方法声明更改为类似的内容以避免错误:
public static int sizeOfListOfSets(List<Set<? extends Object>> list)
Because that would enable you to put any object in that list. 因为这样可以将任何对象放入该列表中。 When you access elements later from your original list reference, it will contain non-Integer objects, although the list is still declared as a
List<Integer>
- which means that you can't rely on what the type says anymore. 当您稍后从原始列表引用访问元素时,它将包含非Integer对象,尽管列表仍然被声明为
List<Integer>
- 这意味着您不能再依赖于类型所说的内容。 Example: 例:
List<Integer> intList = new ArrayList<Integer>();
doSomething(intList);
for (Integer i : intList) {
// i must be an Integer, so doSomething must not
// be able to put non-Integers into that list.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.