无法在Java中创buildLinkedLists数组…?

我正在处理一个稀疏matrix类, 需要使用一个LinkedList数组来存储matrix的值。 数组的每个元素(即每个LinkedList )表示matrix的一行。 并且, LinkedList数组中的每个元素都表示一个列和存储的值。

在我的课上,我有一个数组声明:

 private LinkedList<IntegerNode>[] myMatrix; 

而且,在我的SparseMatrix构造函数中,我尝试定义:

 myMatrix = new LinkedList<IntegerNode>[numRows]; 

我最终得到的错误是

无法创buildLinkedList<IntegerNode>的通用数组。

所以,我有两个问题:

  1. 我做错了什么,和
  2. 为什么数组声明中可以接受的types如果不能创build?

IntegerNode是我创build的一个类。 而且,我所有的类文件都打包在一起。

9 Solutions collect form web for “无法在Java中创buildLinkedLists数组…?”

您不能使用通用数组创build。 这是javagenerics的缺陷/特征。

没有警告的方式是:

  1. 使用列表而不是列表数组:

     List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>(); 
  2. 为列表数组声明特殊的类:

     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 ,并且按照索引顺序遍历列,但是如果不需要这些情况,则HashMapTreeMap快。 获取和设置任意单元格的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来表示图的邻接列表,在大多数情况下,它需要遍历给定顶点的邻接列表,而不是随机访问列表中的某个顶点。

  • 如何定义基本types的genericstypes限制?
  • 为什么Java不允许Throwable的通用子类?
  • Scala通用方法 - 没有ClassTag可用于T
  • 为什么java.util.Properties实现Map <Object,Object>而不是Map <String,String>
  • 通用类的文件名约定
  • 如何在C#中为generics类创build别名?
  • 对于无效genericstypes参数的最佳例外
  • 为什么T在Collections.max()签名中受Object约束?
  • generics和铸造 - 不能将inheritance类转换为基类
  • 在swift中使用协议作为数组types和函数参数
  • generics有什么好处,为什么要使用它们?