我想在java中创建一个哈希表类,我将键值对存储在Linked List的ArrayList中。我通过声明
来做到这一点 ArrayList<LinkedList<T>> storage = new ArrayList();
然后我想创建一个linkList对象,然后我可以使用它来在arrayList的每个索引中创建一个新的链表。我这样做是通过声明:
LinkedList<T> list = new LinkedList<T>();
然后我设置了add函数,将元素添加到LinkedList的第一个索引中,该索引位于arrayList的Hashed键索引中,如下所示:
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的原始声明是不正确的。
答案 0 :(得分:3)
您将ArrayList
容量与 size 混淆。从Oracle Java文档:
每个
ArrayList
实例都有容量。容量是用于存储列表中元素的数组的大小。它始终至少与列表大小一样大。当元素添加到ArrayList
时,其容量会自动增加。除了添加元素具有恒定的摊销时间成本这一事实之外,未指定增长政策的细节。
相反,您应该考虑创建一个普通数组(例如Object[] a = new Object[maxSize]
),您可以在其中以任意索引值实际分配对象(在本例中为链接列表)。如果您只想存储链接列表,请创建一个LinkedList<T>[]
数组。
答案 1 :(得分:2)
如果其中包含0个元素,则无法在索引7处添加列表。您最后只能添加(使用add
方法而不添加索引)或位于不大于当前列表size()
的位置。
当列表为空并且您在索引7处添加内容时,您希望列表在第一个位置包含什么,以及在索引6处包含什么? (我曾经创建了一个list的子类,当加法索引大于列表大小时,用null
填充索引的所有内容,但这种行为不够通用,不能成为List
的一部分。语义。
[编辑回复此处的评论和praseodym的回答]
当首次访问相应位置时,您可以简单地fill the (array) list with nulls替换带有链接列表的那些。 (请务必使用set
而不是add
,这可能也是您想要的。)
或者,您可以创建一个所需大小的数组(默认情况下将填充null
)并通过Arrays.asList
将其“包装”到(不可调整大小的)列表中。然而,您必须忽略“未经检查的转换”警告(不是您在使用数组时可以避免警告)。另外,我建议你阅读“Program to an interface, not an implementation”。