初始化ArrayList <record <t>&gt; [] values; </record <t>

时间:2012-11-28 15:34:36

标签: java generics arraylist

大家好,我该怎么做才能初始化

ArrayList<Record<T>> [] values;

有多少行和列?例如,有三行四列吗?

2 个答案:

答案 0 :(得分:2)

使用泛型类型的数组(例如ArrayList<T>)是一种地狱的方式。以下行甚至不编译:

ArrayList<Record<T>>[] values = new ArrayList<Record<T>>[SIZE_ARRAY];

编译器发出此错误:

Cannot create a generic array of ArrayList<Record<T>>

唯一明智的解决方案是创建一个列表列表:

// create matrix
ArrayList<ArrayList<Record<T>>> matrix = new ArrayList<ArrayList<Record<T>>>();

// add 3 rows:
for (int i = 0; i < 3; i++) {
    ArrayList<Record<T>> row = new ArrayList<Record<T>>();
    matrix.add(row);

    // add 4 elements to each row
    for (int j = 0; j < 4; j++) {
        Record<T> record = ... // get the record
        row.add(record);
    }
}

现在你可以访问[2] [3]中的元素(最后一行的最后一个元素):

Record<T> record = matrix.get(2).get(3);

答案 1 :(得分:0)

只是做:

ArrayList<Record<T>>[] values = (ArrayList<Record<T>>[])new ArrayList<?>[SIZE_ARRAY];

将会有一个未经检查的投射警告,你基本上可以忽略它。

不允许参数化类型的数组创建的真正原因是一种深奥的。 Java中的数组(与通用集合不同)具有(并且始终具有)在运行时检查它们的功能 - 即每次将元素放入其中时,它都会检查该元素是否为数组的组件类型的实例(它在运行时知道)。如果不是,则抛出异常(ArrayStoreException)。

现在,考虑一下参数化类型的数组。如果您知道数组的上述行为,您可能会期望参数化类型的数组会检查放入其中的内容是该参数化类型的实例。除了在Java中不可能在运行时检查某些东西是参数化类型(ArrayList<Something>)的实例。您可以做的最多是检查它是ArrayList,而不是它的参数。

由于它不能完全满足人们的期望,Java设计者决定完全禁止创建参数化类型的数组。您仍然可以创建一个原始类型的数组(例如new ArrayList[5])或一个通配类型的数组(例如new ArrayList<?>[5]),因为在这些情况下, 可以检查如果一个对象是运行时的实例(即obj instanceof ArrayListobj instanceof ArrayList<?>是合法的,但obj instanceof ArrayList<Something>不是合法的。 (他们也可以创建一个特殊情况,参数化类型的数组只检查原始类型的元素,而不是参数化类型,但这会产生不一致。)但是,可能大多数遇到此问题的人都没有考虑这种能力数组在运行时检查它们的元素类型 - 它们可能只是想创建一个正常使用的数组。

您还可以将数组强制转换为参数化数组类型。这是一个未经检查的强制转换,因为如上所述,参数化类型的数组无法满足数组的约定以完全检查其元素类型 - 例如现在,如果您有ArrayList<String>[],则可以将ArrayList<Integer>添加到数组而不会生成异常。然而,99%的人并不关心这个功能,并且未经检查的演员说,嘿,我们知道这个限制,但我们还是想这样做。