我有以下陈述:
List<List<String>> myList = new ArrayList<ArrayList<String>>();
List<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();
第一个给出了编译错误。我们不应该编码接口吗?在这里,我被迫按类而不是接口进行编码。这是一个泛型失败,还是我理解错了?
答案 0 :(得分:5)
应该是:
List<List<String>> myList = new ArrayList<List<String>>();
您需要传入类型,该类型可以是ArrayList
构造函数的接口。换句话说,您需要ArrayList
,其中包含List<String>
类型的对象。然后当你实际把东西放到列表中时:
mList.add(new ArrayList<String>());
答案 1 :(得分:3)
第一个应该是:
List<List<String>> myList = new ArrayList<List<String>>();
语义如下:类型myList
是包含List
类型对象的List<String>
。实现类是ArrayList
,能够包含List<String>
类型的对象。
一旦你想将一个对象添加到myList,就可以这样:
myList.add(new ArrayList<String>());
答案 2 :(得分:2)
这是一个已知问题。如果你这样做会有其他问题。
考虑以下代码:
List<List<String>> myList = new ArrayList<ArrayList<String>>();
myList.push( new LinkedList<String>() ); // impossible to catch, because java don't have generic in runtime
ArrayList<ArrayList<String>> list2 = (ArrayList<ArrayList<String>>) myList; // ok
ArrayList<String> something = list2.get(0); // doh! impossible to assign LinkedList to ArrayList
答案 3 :(得分:1)
这里的问题有点微妙。为了使其正确,您需要:
List<List<String>> myList = new ArrayList<List<String>>();
myList的定义是要求字符串列表,但是您将其实现为字符串数组列表,并且这些列表不匹配。如果您稍后尝试过以下内容,这将成为一个问题:
myList.add(new LinkedList<String>());
字符串列表的定义可以,但违反了实现的定义。 LinkedList 是一个列表,但不是一个ArrayList。
如果你想强制它是一个字符串数组列表,那么你可以使用ArrayList<ArrayList<String>> myList
定义,但通常最好保留接口。
使用我修改过的代码,你仍然可以在实现中使用字符串的ArrayLists的ArrayList。
List<List<String>> myList = new ArrayList<List<String>>();
for (int i = 0; i < rowSize; i++)
{
myList.add(new ArrayList<String>());
}
它同意myList的定义为字符串列表,但你仍然可以获得在幕后使用ArrayList的好处。
答案 4 :(得分:1)
你可以这样做:
List<? extends List<String>> myList = new ArrayList<ArrayList<String>>();
你的第一行不起作用的原因是你不能List<A> = List<B>
,即使B
是A
的子类型(因为它在这里,ArrayList是一个子类型列表)。否则会违反类型安全。这是一个基本的泛型功能,许多初学者都遇到了麻烦。但是,您可以List<? extends A> = List<B>
;在这种情况下,? extends A
是可以包含B 的通配符。作为交换,你失去了向List<? extends A>
添加东西的能力(规则:扩展生产者,超级消费者),这消除了安全问题。