2

我无法理解如何在 Java 中初始化 ArrayLists 数组,有人可以解释这行代码中发生了什么吗?

edges = (ArrayList<Integer>[]) new ArrayList[nodeCount + 1];
4

6 回答 6

6

让我们逐个空间地打破它。
edges是类型的变量ArrayList<Integer>[]
=是将右手分配给左手的赋值运算符是对类型的变量的强制转换
(ArrayList<Integer>[])。意味着我们为一个包含未知元素
new ArrayList[nodeCount + 1]的数组分配空间。ArrayListnodeCount+1

这是初始化数组的一种非常糟糕的方法。它的作用是创建一个数组并将元素转换为整数。

替代: edges = new ArrayList<Integer>(nodeCount+1);

说明:该类ArrayList有一个可以指定其长度*的构造函数,这就是我在这里使用的。
注意:根据@Rohit Jain,它没有指定长度,而是指定初始容量。

于 2013-08-09T12:53:13.220 回答
3

您不能创建组件类型为参数化类型的数组。它不是类型安全的。虽然您可以创建一个组件类型为原始类型的数组,但这也不是类型安全的。考虑以下示例:

List<Integer>[] list = null;       // Declaration is OK
list = new ArrayList<Integer>[5];  // Compiler error: Generic array creation
list = new ArrayList[5];   // Compiles fine. But not safe. Gives warning

假设您创建了一个原始类型数组。让我们看看这可能意味着什么:

List<Integer>[] list = new ArrayList[10]; // Not type safe

Object[] objArr = list;   // We can assign List<Integer>[] to Object[]

// We can add even ArrayList<String> in Object[]
// This will successfully compile, and run. 
objArr[0] = new ArrayList<String>() {   
    {
        add("rohit"); add("jain");
    }
}; 

// Here's the problem. It will compile fine, but at runtime will throw 
// ClassCastException
Integer val = list[0].get(0);

List另一种方法是创建一个List

List<List<Integer>> edges = new ArrayList<List<Integer>>();

建议阅读:-

Angelika Langer 通用常见问题解答

于 2013-08-09T12:52:23.933 回答
1

这不会初始化ArrayList - 它会初始化ArrayLists 数组

  • new ArrayList[nodeCount + 1]= 创建一个带有插槽的ArrayList对象数组nodeCount + 1
  • (ArrayList<Integer>[])ArrayList= 将其转换为“反过来可能只包含对象的对象数组Integer”。这是必需的,因为 java 的数组声明语法显然无法处理泛型(刚刚尝试过——我以前从来不需要这个)。

可能是一个误解,作者实际上想初始化一个ArrayList容量为nodeCount+ 1. 正确的代码是

edges = new ArrayList<Integer>(nodeCount + 1);

实际上容量参数只是一种优化,因为ArrayList对象会根据需要自动增长。但是,如果您已经知道需要多少条目,则可以从一开始就创建具有足够容量的列表。

于 2013-08-09T13:03:36.380 回答
1

在上面的行中,您正在创建一个数组ArrayList,您可以用ArrayList更简单的类型替换以帮助您理解,例如字符串数组:

edges = (String[]) new String[nodeCount + 1];

nodeCount + 1对应于数组的大小。数组不能超过这个数量的元素。

请注意,使用参数化数组ArrayList是非常奇怪的,并且容易产生误解和错误。我会在List<List<Integer>>这里使用 a ,例如:

edges = new ArrayList<List<Integer>>();
于 2013-08-09T12:54:07.817 回答
1

这一行定义了一个数组,就像任何其他数组一样:exampe new Object[0], new String[0], ...

就像任何其他数组一样,这些值将以空值启动。对于原始类型是 '0',对于对象/类是null. 所以你应该在使用它之前启动不同的数组列表:

edges =  new ArrayList<Integer>[nodeCount + 1];
for(int i=0; i<edges.length; i++){
    edges[i] = new ArrayList<Integer>();
}
于 2013-08-09T12:55:52.250 回答
0
new ArrayList[nodeCount + 1] 

创建一个新的ArrayList数组,其长度为nodeCount + 1;

然后

(ArrayList<Integer>[]) 

是一个转换操作,它将您刚刚创建的数组转换为一个数组ArrayList<Integer>

于 2013-08-09T12:53:41.220 回答