无法在 Java 中创建 LinkedLists 数组...?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/217065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot create an array of LinkedLists in Java...?
提问by kafuchau
I'm working on a sparse matrix class that needsto use an array of LinkedList
to store the values of a matrix. Each element of the array (i.e. each LinkedList
) represents a row of the matrix. And, each element in the LinkedList
array represents a column and the stored value.
我正在研究一个需要使用数组LinkedList
来存储矩阵值的稀疏矩阵类。数组的每个元素(即 each LinkedList
)代表矩阵的一行。并且,LinkedList
数组中的每个元素代表一列和存储的值。
In my class, I have a declaration of the array as:
在我的课堂上,我将数组声明为:
private LinkedList<IntegerNode>[] myMatrix;
And, in my constructor for the SparseMatrix
, I try to define:
而且,在我的构造函数中SparseMatrix
,我尝试定义:
myMatrix = new LinkedList<IntegerNode>[numRows];
The error I end up getting is
我最终得到的错误是
Cannot create a generic array of
LinkedList<IntegerNode>
.
无法创建
LinkedList<IntegerNode>
.
So, I have two issues with this:
所以,我有两个问题:
- What am I doing wrong, and
- Why is the type acceptable in the declaration for the array if it can't be created?
- 我做错了什么,以及
- 如果无法创建数组,为什么该类型在数组的声明中是可以接受的?
IntegerNode
is a class that I have created. And, all of my class files are packaged together.
IntegerNode
是我创建的一个类。而且,我所有的类文件都打包在一起。
采纳答案by Sergey
You can't use generic array creation. It's a flaw/ feature of java generics.
您不能使用通用数组创建。这是java泛型的一个缺陷/特性。
The ways without warnings are:
没有警告的方法是:
Using List of Lists instead of Array of Lists:
List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
Declaring the special class for Array of Lists:
class IntegerNodeList { private final List< IntegerNode > nodes; }
使用列表列表而不是列表数组:
List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
声明列表数组的特殊类:
class IntegerNodeList { private final List< IntegerNode > nodes; }
回答by Fredrik
For some reason you have to cast the type and make the declaration like this:
出于某种原因,您必须强制转换类型并进行如下声明:
myMatrix = (LinkedList<IntegerNode>[]) new LinkedList<?>[numRows];
回答by Paul Croarkin
There is no generic array creation in Java 1.5 (or 1.6 as far as I can tell). See https://community.oracle.com/message/4829402.
在 Java 1.5(或据我所知 1.6)中没有通用数组创建。请参阅https://community.oracle.com/message/4829402。
回答by Dov Wasserman
Aside from the syntax issues, it seems strange to me to use an array and a linked list to represent a matrix. To be able to access arbitrary cells of the matrix, you would probably want an actual array or at least an ArrayList
to hold the rows, as LinkedList
must traverse the whole list from the first element to any particular element, an O(n)
operation, as opposed to the much quicker O(1)
with ArrayList
or an actual array.
除了语法问题之外,使用数组和链表来表示矩阵对我来说似乎很奇怪。为了能够访问矩阵的任意单元格,您可能需要一个实际的数组或至少一个ArrayList
来保存行,因为LinkedList
必须遍历从第一个元素到任何特定元素的整个列表,一个O(n)
操作,而不是很多O(1)
使用ArrayList
或实际数组更快。
Since you mentioned this matrix is sparse, though, perhaps a better way to store the data is as a map of maps, where a key in the first map represents a row index, and its value is a row map whose keys are a column index, with the value being your IntegerNode class. Thus:
既然你提到这个矩阵是稀疏的,也许存储数据的更好方法是映射映射,其中第一个映射中的键表示行索引,其值是行映射,其键是列索引, 值为您的 IntegerNode 类。因此:
private Map<Integer, Map<Integer, IntegerNode>> myMatrix = new HashMap<Integer, Map<Integer, IntegerNode>>();
// access a matrix cell:
int rowIdx = 100;
int colIdx = 30;
Map<Integer, IntegerNode> row = myMatrix.get(rowIdx); // if null, create and add to matrix
IntegerNode node = row.get(colIdx); // possibly null
If you need to be able to traverse the matrix row by row, you can make the row map type a TreeMap
, and same for traversing the columns in index order, but if you don't need those cases, HashMap
is quicker than TreeMap
. Helper methods to get and set an arbitrary cell, handling unset null values, would be useful, of course.
如果您需要能够逐行遍历矩阵,您可以使行映射类型为 a TreeMap
,并且以索引顺序遍历列也是如此,但如果您不需要这些情况,HashMap
则比TreeMap
. 获取和设置任意单元格、处理未设置的空值的辅助方法当然很有用。
回答by user306708
myMatrix = (LinkedList<IntegerNode>[]) new LinkedList[numRows];
myMatrix = (LinkedList<IntegerNode>[]) new LinkedList[numRows];
casting this way works but still leaves you with a nasty warning:
以这种方式进行转换是有效的,但仍然会给您一个令人讨厌的警告:
"Type safety: The expression of type List[] needs unchecked conversion.."
“类型安全:List[] 类型的表达式需要未经检查的转换..”
Declaring a special class for Array of Lists:
class IntegerNodeList { private final List< IntegerNode > nodes; }
为列表数组声明一个特殊的类:
class IntegerNodeList { private final List< IntegerNode > nodes; }
is a clever idea to avoid the warning. maybe a little bit nicer is to use an interface for it:
是避免警告的聪明主意。也许更好一点的是使用它的接口:
public interface IntegerNodeList extends List<IntegerNode> {}
then
然后
List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];
compiles without warnings.
编译没有警告。
doesn't look too bad, does it?
看起来还不错吧?
回答by Bob
class IntegerNodeList extends LinkedList<IntegerNode> {}
IntegerNodeList[] myMatrix = new IntegerNodeList[numRows];
回答by Andrii
List<String>[] lst = new List[2];
lst[0] = new LinkedList<String>();
lst[1] = new LinkedList<String>();
No any warnings. NetBeans 6.9.1, jdk1.6.0_24
没有任何警告。NetBeans 6.9.1、jdk1.6.0_24
回答by Ryan
If I do the following I get the error message in question
如果我执行以下操作,则会收到有问题的错误消息
LinkedList<Node>[] matrix = new LinkedList<Node>[5];
But if I just remove the list type in the declaration it seems to have the desired functionality.
但是,如果我只是删除声明中的列表类型,它似乎具有所需的功能。
LinkedList<Node>[] matrix = new LinkedList[5];
Are these two declarations drastically different in a way of which I'm not aware?
这两个声明是否以我不知道的方式截然不同?
EDIT
编辑
Ah, I think I've run into this issue now.
啊,我想我现在遇到了这个问题。
Iterating over the matrix and initializing the lists in a for-loop seems to work. Though it's not as ideal as some of the other solutions offered up.
迭代矩阵并在 for 循环中初始化列表似乎有效。尽管它不如提供的其他一些解决方案那么理想。
for(int i=0; i < matrix.length; i++){
matrix[i] = new LinkedList<>();
}
回答by Yiling
You need an array of List, one alternative is to try:
您需要一个 List 数组,另一种方法是尝试:
private IntegerNode[] node_array = new IntegerNode[sizeOfYourChoice];
Then node_array[i]
stores the head(first) node of a ArrayList<IntegerNode>
or LinkedList<IntegerNode>
(whatever your favourite list implementation).
然后node_array[i]
存储 a ArrayList<IntegerNode>
or的头(第一个)节点LinkedList<IntegerNode>
(无论您喜欢什么列表实现)。
Under this design, you lose the random access method list.get(index)
, but then you could still traverse the list starting with the head/fist node store in the type safe array.
在这种设计下,您失去了随机访问方法list.get(index)
,但是您仍然可以从类型安全数组中的头/拳节点存储开始遍历列表。
This might be an acceptable design choice depending on your use case. For instance, I use this design to represent an adjacency list of graph, in most use cases, it requires traversing the adjacency list anyway for a given vertex instead of random access some vertex in the list.
根据您的用例,这可能是一个可接受的设计选择。例如,我用这个设计来表示一个图的邻接表,在大多数用例中,它需要遍历邻接表来遍历给定的顶点,而不是随机访问列表中的某个顶点。