无法在Java中创buildLinkedLists数组…?
我正在处理一个稀疏matrix类, 需要使用一个LinkedList
数组来存储matrix的值。 数组的每个元素(即每个LinkedList
)表示matrix的一行。 并且, LinkedList
数组中的每个元素都表示一个列和存储的值。
在我的课上,我有一个数组声明:
private LinkedList<IntegerNode>[] myMatrix;
而且,在我的SparseMatrix
构造函数中,我尝试定义:
myMatrix = new LinkedList<IntegerNode>[numRows];
我最终得到的错误是
无法创build
LinkedList<IntegerNode>
的通用数组。
所以,我有两个问题:
- 我做错了什么,和
- 为什么数组声明中可以接受的types如果不能创build?
IntegerNode
是我创build的一个类。 而且,我所有的类文件都打包在一起。
您不能使用通用数组创build。 这是javagenerics的缺陷/特征。
没有警告的方式是:
-
使用列表而不是列表数组:
List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
-
为列表数组声明特殊的类:
class IntegerNodeList { private final List< IntegerNode > nodes; }
出于某种原因,您必须将types转换为以下声明:
myMatrix = (LinkedList<IntegerNode>[]) new LinkedList<?>[numRows];
除了语法问题之外,使用数组和链表来表示一个matrix似乎很奇怪。 为了能够访问matrix的任意单元格,您可能需要一个实际的数组或至less一个ArrayList
来存放行,因为LinkedList
必须遍历从第一个元素到任何特定元素的整个列表,一个O(n)
操作,而不是更快的O(1)
与ArrayList
或实际的数组。
既然你提到这个matrix是稀疏的,但是,也许存储数据的一个更好的方法是作为映射的映射,其中第一个映射中的键代表行索引,并且其值是行映射,其键是列索引,值是你的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
如果您需要能够逐行遍历matrix,则可以使行映射types为TreeMap
,并且按照索引顺序遍历列,但是如果不需要这些情况,则HashMap
比TreeMap
快。 获取和设置任意单元格的Helper方法,处理未设置的null值当然是有用的。
class IntegerNodeList extends LinkedList<IntegerNode> {} IntegerNodeList[] myMatrix = new IntegerNodeList[numRows];
myMatrix = (LinkedList<IntegerNode>[]) new LinkedList[numRows];
以这种方式铸造的作品,但仍然留下一个令人讨厌的警告:
“types安全性:List []types的expression式需要未经检查的转换。”
为列表数组声明一个特殊的类:
class IntegerNodeList { private final List< IntegerNode > nodes; }
是避免警告的一个聪明的想法。 也许更好一点是使用它的接口:
public interface IntegerNodeList extends List<IntegerNode> {}
然后
List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];
编译没有警告。
看起来不错,是吗?
List<String>[] lst = new List[2]; lst[0] = new LinkedList<String>(); lst[1] = new LinkedList<String>();
没有任何警告。 NetBeans 6.9.1,jdk1.6.0_24
在Java 1.5中没有创build通用数组(尽pipe我能说明的是1.6)。 请参阅https://community.oracle.com/message/4829402 。
如果我执行以下操作,则会收到错误消息
LinkedList<Node>[] matrix = new LinkedList<Node>[5];
但是,如果我只是在声明中删除列表types,它似乎具有所需的function。
LinkedList<Node>[] matrix = new LinkedList[5];
这两个声明是否以我不知道的方式截然不同?
编辑
啊,我想我现在已经遇到了这个问题。
迭代matrix并在for循环中初始化列表似乎工作。 虽然它不像其他解决scheme那样理想。
for(int i=0; i < matrix.length; i++){ matrix[i] = new LinkedList<>(); }
你需要一个List的数组,一个替代方法是尝试:
private IntegerNode[] node_array = new IntegerNode[sizeOfYourChoice];
然后, node_array[i]
存储ArrayList<IntegerNode>
或LinkedList<IntegerNode>
的头(第一个)节点(无论您最喜欢的列表实现如何)。
在这种devise下,您将失去随机访问方法list.get(index)
,但是您仍然可以遍历以types安全数组中头/节点存储开始的列表。
这可能是一个可接受的deviseselect取决于您的使用情况。 例如,我使用这种devise来表示图的邻接列表,在大多数情况下,它需要遍历给定顶点的邻接列表,而不是随机访问列表中的某个顶点。