如何在Java中正确定义一个链表数组?

5

我尝试在Java中定义一个链表数组,如下所示,编译没有问题,但是会生成2个警告信息。

 LinkedList<Long> [] hashtable = new LinkedList[10];

warning: [rawtypes] found raw type: LinkedList
    LinkedList<Long> [] hashtable = new LinkedList[10];
                                        ^
  missing type arguments for generic class LinkedList<E>
  where E is a type-variable:
    E extends Object declared in class LinkedList
HashTable.java:13: warning: [unchecked] unchecked conversion
    LinkedList<Long> [] hashtable = new LinkedList[10];
                                    ^
  required: LinkedList<Long>[]
  found:    LinkedList[]

所以,我尝试了

 LinkedList<Long> [] hashtable = new LinkedList<Long>[10];

但这一次它甚至无法编译,而是生成了以下错误。
HashTable.java:13: error: generic array creation
    LinkedList<Long> [] hashtable = new LinkedList<Long>[10];
                                    ^
1 error

那么,我应该如何正确地定义我的链表数组?
3个回答

9

这是创建数组的正确方式:

@SuppressWarnings("unchecked") LinkedList<Long> [] hashtable = new LinkedList[10];

无法创建参数化类型的数组

您无法创建参数化类型的数组。例如,以下代码将无法编译:

List<Integer>[] arrayOfLists = new List<Integer>[2];  // compile-time error

以下代码展示了将不同类型插入数组时会发生的情况:
Object[] strings = new String[2];
strings[0] = "hi";   // OK
strings[1] = 100;    // An ArrayStoreException is thrown.

如果你尝试使用通用列表做同样的事情,会出现问题:

Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                            // but the runtime can't detect it.

如果允许参数化列表的数组,则先前的代码将无法抛出所需的ArrayStoreException。
取自docs.oracle.com 那么我可以在hashtable[]中存储什么?
这是否意味着现在我可以在 hashtable[0] 中拥有一个字符串的链表,以及在 hashtable1 中拥有一个Long的链表,如果我执行 LinkedList [] hashtable = new LinkedList[10]?
不,编译器不会直接允许您将LinkedList存储到hashtable数组中。以下代码片段将无法编译:
hashtable[0] = new LinkedList<String>();

然而,您可以不使用类型参数存储LinkedList,甚至是LinkedList的子类:

@SuppressWarnings("unchecked") LinkedList<Long>[] hashtable = new LinkedList[10];

hashtable[0] = new LinkedList<Long>();
hashtable[1] = new MyLinkedList<Long>();
hashtable[2] = new LinkedList();
hashtable[3] = new MyLinkedList();

如果将数组转换为LinkedList[],则可以存储LinkedList。但是,您只能存储LinkedList,无法存储其他任何内容:
LinkedList[] rawHashTable = hashtable;
rawHashTable[4] = new LinkedList<String>();

Object[] objectHashTable = rawHashTable;
objectHashTable[5] = "This line will throw an ArrayStoreException ";

这是我一开始做的,但它产生了两个警告,这让我感到这种方法真的不太安全。 - mynameisJEFF
@mynameisJEFF,我已经添加了一些更多的细节,说明为什么这是一个正确的方法。你可以使用“@SuppressWarnings("unchecked")”来抑制这个警告。 - bedrin
那么,这是否意味着如果我执行LinkedList<Long>[] hashtable = new LinkedList[10],我现在可以在hashtable [0]中拥有一个字符串的链表和在hashtable [1]中拥有一个长整型的链表? - mynameisJEFF
@mynameisJEFF 我已经更新了我的答案,并添加了一个关于我们可以在_hashtable_中存储什么的部分。 - bedrin
我觉得我现在有点明白你的意思了。所以基本上,如果我定义了 LinkedList<Long>[] hashtable = new LinkedList[10];,那么我必须在每个 hashtable[i] 条目中初始化一个新的链表(它必须是类型为 Long 的链表),以便将 Long 数据的链表存储到数组中。我的理解正确吗? - mynameisJEFF
@mynameisJEFF 没错! - bedrin

6

首先定义一个数组大小,其中每个元素都是一个LinkedList。

LinkedList<Long> hashTable[] = new LinkedList[10];

现在,由于数组中的每个元素本身都是一个LinkedList,而且它们全部都是null,因此需要对它们进行初始化。因此,
for (int i=0;i<10;i++)
        hashTable[i] = new LinkedList<Long>();

如果你想要向列表中添加数据,那么可以采用以下方式:
hashTable[i].add(YOUR_LONG_DATA_HERE);

最后要迭代,
for (int i=0;i<10;i++){
        for (Long j: hashTable[i])
            System.out.println(j);
}

0
如果您需要一个LinkedList的列表/数组,您可以使用一个初始大小为10的ArrayList来保存该集合。
这里是另一种可尝试的方法:
ArrayList<LinkedList<Long>> list = new  ArrayList<LinkedList<Long>>(10);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接