如何创建集合数组?

时间:2010-06-07 19:51:20

标签: java

  

可能重复:
  What’s the reason I can’t create generic array types in Java?

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

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

4 个答案:

答案 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];
}