我正在尝试创建一个字符串列表列表,
List<List<String>> string= new ArrayList<ArrayList<String>>();
并且出现类型不匹配错误:无法从ArrayList<ArrayList<String>>
转换为List<List<String>>
。
我知道我可以改变
List<List<String>> to ArrayList<ArrayList<String>>
它会正常工作。
但我只是想知道它为什么不让它发生?简单的List<Object>
可以参考ArrayList<Object>
,那么这有什么不同呢?
答案 0 :(得分:1)
因为List<List<String>>
会接受不是数组列表的其他字符串列表,这不是最初声明类型的方式。例如,如果您转换为List<List<String>>
,则从技术上讲,您可以向其添加LinkedList<String>
!这不是ArrayList<String>
。允许该转换会有效地破坏泛型类型系统。
换句话说,您可以转换为List<ArrayList<String>>
。但不是List<List<String>>
。
答案 1 :(得分:1)
List<List<String>> string = new ArrayList<List<String>>()
这是正确的做法。
问候,
答案 2 :(得分:1)
您无法将ArrayList<ArrayList<String>>
分配给List<List<String>>
,因为它违反了泛型的编译时类型安全承诺。如果此作业有效,那么我们可以将LinkedList<String>
插入ArrayList<ArrayList<String>>
并破坏类型安全。
典型的例子是List<Number>
不是List<Integer>
。它可以很容易地通过矛盾来表现出来。
List<Integer> ints = new ArrayList<Integer>();
ints.add(42);
//This results in compiler error
/* List<Number> nums = ints; */
//If it were not and an error, then you could
List<Number> nums = ints;
//Now you can insert doubles into a list of `Number`s
nums.add(0.1);
//This would allow 0.1 to assign to an int
Integer x=ints.get(1);
//This will cause ClassCastException and
//violate type-safety provided by generics.
答案 3 :(得分:0)
除了我们已经说过的内容之外,我还想注意你写的定义: 的ArrayList&GT;() 适合你,但还不够好。
你应该说:
列表&gt; list = new ArrayList&gt;();
如果存在抽象类或接口,则规则永远不会将具体类写入泛型定义和赋值的左侧部分。我的版本允许将来更改列表实现,而不会对使用此数据结构的代码进行任何更改。
此外,List是一个集合。如果您使用特定列表的功能无关紧要(例如,如果您只是迭代此列表),您可以说出以下内容:
收集和GT; list = new ArrayList&gt;();
在这种情况下,您甚至可以将列表更改为设置:
收集和GT; list = new LinkedHashSet&gt;();