【问题标题】:Adding a element of Generic type <T> to an arrayList of LinkedList's将通用类型 <T> 的元素添加到 LinkedList 的 arrayList
【发布时间】:2012-11-10 22:46:27
【问题描述】:

我想在 java 中创建一个哈希表类,将键、值对存储在链接列表的 ArrayList 中。我通过声明

来做到这一点
 ArrayList<LinkedList<T>> storage = new ArrayList();

然后我想创建一个链接列表对象,然后我可以使用它在 arrayList 的每个索引内创建一个新的链接列表。我通过声明来做到这一点:

  LinkedList<T> list = new LinkedList<T>();

然后我设置了 add 函数,将元素添加到 LinkedList 的第一个索引,该索引位于 arrayList 的哈希键索引内,如下所示:

public void add(K key, T value){    
int arrayListIndex = (key.hashCode()) % this.initialCapacity;
    System.out.println(arrayListIndex); //This tells us where we access the Array List;


    if (hashBrown.get(arrayListIndex) == null){

        hashBrown.add(arrayListIndex, list);
        hashBrown.get(arrayListIndex).addFirst(value);
    }
}

每次运行此代码时,我都会收到一个错误,其中我的索引为 7,我的大小为 0。这会导致错误:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:571)
    at java.util.ArrayList.get(ArrayList.java:349)
    at FastHashtable.add(FastHashtable.java:72)
    at FastHashtable.main(FastHashtable.java:145)

我无法追踪此索引越界错误的来源,任何人都可以提供建议。我在使用 ArrayLists 方面相当陌生,这让我认为我最初对 arrayList 的声明是不正确的。

【问题讨论】:

    标签: java list hashtable indexoutofboundsexception


    【解决方案1】:

    您将ArrayLists 容量 与其大小 混淆了。来自 Oracle Java 文档:

    每个ArrayList 实例都有一个容量。容量是用于存储列表中元素的数组的大小。它总是至少与列表大小一样大。随着元素被添加到ArrayList,其容量会自动增长。除了添加元素具有恒定的摊销时间成本这一事实之外,没有指定增长策略的细节。

    相反,您应该考虑创建一个普通数组(例如Object[] a = new Object[maxSize]),您可以在其中实际分配任意索引值的对象(在这种情况下为链表)。如果您只想存储链表,请创建一个LinkedList&lt;T&gt;[] 数组。

    【讨论】:

    • 听起来像普通的对象数组是要走的路
    • @DerekDrummond 如果你不想调整数组的大小,那么原则上是可以的,但是一个通用对象数组(即你的链表)很难处理(并且首先要创建) .
    • 如果您有兴趣,可以查看Java HashMap source code,它的核心是动态调整大小的对象数组 (Entry[])。
    • 在 20 分钟内,我使用数组而不是数组列表完成了所有工作,这需要 3 个小时的挫败感。
    【解决方案2】:

    如果列表中有 0 个元素,则无法添加到索引为 7 的列表。您只能在末尾添加(使用不带索引的add 方法)或在不大于当前列表的size() 的位置。

    当列表为空并且您在索引 7 处添加一些内容时,您希望列表在第一个位置包含什么,以及在索引 6 处包含什么? (我曾经创建了一个 list 的子类,当添加索引大于列表大小时,用null 填充索引的所有内容,但这种行为不够普遍,不能成为List 语义的一部分。


    [根据此处的评论和 praseodym 的回答进行编辑]

    当第一次访问相应位置时,您可以简单地fill the (array) list with nulls 将它们替换为链表。 (不过,请务必使用set 而不是add,这可能也是您想要的。) 或者,您可以创建所需大小的数组(默认情况下将充满nulls)并通过Arrays.asList 将其“包装”到(不可调整大小的)列表中。但是,您必须忽略“未经检查的转换”警告(并不是说您可以在使用数组时避免警告)。另外,我建议您阅读“Program to an interface, not an implementation”。

    【讨论】:

    • 听起来工作量比需要的多,创建所有这些额外的 arrayList 索引会破坏效率
    • 错了?哪些额外的arrayLists? (而且,出于好奇,是什么让您认为您可以构建比 HashMap 更快的哈希表?)
    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2021-12-30
    • 1970-01-01
    相关资源
    最近更新 更多