如何创建集合数组?

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

HashSet[] rows = new HashSet[9]; 

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

答案很简单: 不要将数组与generics混合!

使用哈希集列表:

 ArrayList> rows = new ArrayList>(); 

这里的问题是Java规范不允许您声明generics对象的数组。

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

 HashSet[] rows = new HashSet[9]; for (int i = 0; i < rows.length; ++i) rows[i] = new HashSet(); 

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

 ((HashSet)rows[0]).add(4); 

旁注:如果您觉得先锋只是下载Trove Collections框架,该框架具有非generics,高度优化的整数哈希集版本,可以使用原始类型,我说的是TIntHashSet类:它将解决您的问题和你最终会得到更快的代码。

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

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

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

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

本书的generics章节以PDF格式提供 。

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

 Set rows[] = new HashSet[3]; for (int i = 0; i < rows.length; i++) { rows[i] = new HashSet(); } 

每当你链接generics或嵌套这样的数据结构时,就该退一步思考你真正想要做的事情。

如果将它封装在包装类中会更好吗? 它可能会使事情变得不那么复杂。 从现在起一周后你必须在一些简单数据类型的数组的arraylists的数组中调试一些东西,因为你以为你只是继续包装它们,你会很抱歉。

-edit:数组是非法的? Point指出。 我仍然觉得这里的论点是有道理的。

你正在使用Java; 不要害怕做一些额外的课程。

 public class MyIntegers { private HashSet theIntegers; // wrap methods public boolean add(Integer i) { return theIntegers.add(i); } public boolean contains(Integer i)... public boolean remove(Integer i)... } // later... public static void main(String[] args) { MyIntegers[] rows = new MyIntegers[NUM_ROWS]; }