可能重复:
What’s the reason I can’t create generic array types in Java?
HashSet<Integer>[] rows = new HashSet<Integer>[9];
给我一个编译错误:通用数组创建。
答案 0 :(得分:21)
简单的答案:不要将数组与泛型混合使用!
使用散列集列表:
ArrayList<HashSet<Integer>> rows = new ArrayList<HashSet<Integer>>();
这里的问题是Java规范不允许您声明泛型对象数组。
它的解决方法是使用通配符,但是你将失去类型安全性:
HashSet<?>[] rows = new HashSet<?>[9];
for (int i = 0; i < rows.length; ++i)
rows[i] = new HashSet<Integer>();
在您的情况下,当您要检查项目是否包含时,这不会产生问题:您可以轻松地执行rows[0].contains(4)
但是在添加新内容时,您将被迫将行转换为正确的类型并禁止未经检查的强制转换警告:
((HashSet<Integer>)rows[0]).add(4);
附注:如果您觉得先锋只是下载Trove Collections框架,该框架具有非泛型,高度优化的整数哈希集版本,可以使用原始类型,我'我在谈论TIntHashSet
课:它会解决你的问题,你最终会得到更快的代码。
答案 1 :(得分:5)
引用Joshua Bloch撰写的Effective Java Second edition,page 119
因为这些根本 差异,数组和泛型 不能很好地混合。例如,它是 非法创建一个数组 泛型类型,参数化类型或 一个类型参数。这些阵列都不是 创建表达式是合法的:
new List<E>[], new List<String>[], new E[]
。所有这些都将导致泛型数组 编译时创建错误。为什么创建泛型是非法的 阵列?因为它不是类型安全的。如果 它是合法的,由演员生成 编译器在其他方面正确 程序可能会在运行时失败
ClassCastException
。这会违反 提供的基本保证 通用类型系统。
(我省略了解释通用类型擦除的部分)
本书的泛型章节是available as a PDF。
答案 2 :(得分:3)
您可以在类型声明中声明泛型,但不能在实际分配对象时声明。不确定确切的原因,也许是为了重新强化在编译时不保留某些泛型信息的概念。
Set<Integer> rows[] = new HashSet[3];
for (int i = 0; i < rows.length; i++) {
rows[i] = new HashSet<Integer>();
}
答案 3 :(得分:1)
每当你链接泛型或嵌套这样的数据结构时,是时候退后一步思考你真正想要做的事情了。
如果将它封装在包装类中会更好吗?它可能会使事情变得不那么复杂。从现在开始的一周,你必须在一些简单数据类型的数组的arraylists的数组中调试一些东西,因为你以为你只是继续包装它们,你会很抱歉。
-edit:数组是非法的?点指出。我仍然觉得这里的论点是存在的。
你正在使用Java;不要害怕做一些额外的课程。
public class MyIntegers {
private HashSet<Integer> 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];
}