如何创建集合数组?

Mur*_*ali 17 java

可能重复:
我无法在Java中创建通用数组类型的原因是什么?

HashSet<Integer>[] rows = new HashSet<Integer>[9];
Run Code Online (Sandbox Code Playgroud)

给我一个编译错误:通用数组创建.

Jac*_*ack 21

简单的答案:不要将数组与泛型混合!

使用哈希集列表:

ArrayList<HashSet<Integer>> rows = new ArrayList<HashSet<Integer>>();
Run Code Online (Sandbox Code Playgroud)

这里的问题是Java规范不允许您声明泛型对象的数组.

解决方法是使用通配符,但您将失去类型安全性:

HashSet<?>[] rows = new HashSet<?>[9];

for (int i = 0; i < rows.length; ++i)
    rows[i] = new HashSet<Integer>();
Run Code Online (Sandbox Code Playgroud)

在您的情况下,当您要检查项目是否包含时,这不会产生问题:您可以轻松地执行此操作,rows[0].contains(4)但在添加新内容时,您将被迫将行转换为正确的类型并禁止取消选中警告施展本身:

((HashSet<Integer>)rows[0]).add(4);
Run Code Online (Sandbox Code Playgroud)

旁注:如果您觉得先锋只是下载Trove Collections框架,该框架具有非泛型,高度优化的整数散列集版本,可以使用原始类型,我在谈论TIntHashSet类:它将解决您的问题,而您最终会有更快的代码.

  • @ wizard @:是的你(他的意思是"不要把它们混合在一起",而不是"不要把它们混淆在一起.")如果它们是无类型的,你只会得到原始类型的警告.那不是更正确的. (2认同)

Jus*_*tin 7

您可以在类型声明中声明泛型,但不能在实际分配对象时声明。不确定确切的原因,也许是为了强化一些泛型信息在编译时不保留的概念。

Set<Integer> rows[] = new HashSet[3];
for (int i = 0; i < rows.length; i++) {
 rows[i] = new HashSet<Integer>();
}
Run Code Online (Sandbox Code Playgroud)


Pow*_*ord 5

引用Joshua Bloch撰写的Effective Java Second edition,第119页

由于这些基本差异,阵列和泛型不能很好地混合.例如,创建泛型类型,参数化类型或类型参数的数组是非法的.这些数组创建表达式都不合法:new List<E>[], new List<String>[], new E[].所有这些都会在编译时导致通用数组创建错误.

为什么创建通用数组是非法的?因为它不是类型安全的.如果它是合法的,那么编译器在正确的程序中生成的强制转换可能会在运行时失败 ClassCastException.这将违反通用类型系统提供的基本保证.

(我省略了解释通用类型擦除的部分)

本书的泛型章节以PDF格式提供.