没有IndexOutOfBounds Exception的索引加法

时间:2012-10-15 08:09:20

标签: java

我有n个对象,每个对象都有一个识别号码。我得到它们未分类,但索引范围(0, n-1)用于识别它们。我希望尽可能快地访问它们。我认为ArrayList是最好的选择,我会在ArrayList的位置添加带有标识符n的对象,索引为n

list.add(identifier, object);

问题在于,当我添加对象时,我得到一个IndexOutOfBounds Exception因为我将它们添加为未排序而size()更小,但我知道之前的位置也将被填充。

另一种选择是使用HashMap,但我认为这会降低性能。

你知道一个具有上述行为的集合吗?

4 个答案:

答案 0 :(得分:2)

  

你知道一个具有上述行为的集合吗?

听起来你需要一个普通的旧Java数组。如果你需要它作为集合,那么使用“Arrays.asList(...)”为它创建一个List包装器。

现在,如果你需要在数组/集合中添加或删除元素,这将无效,但听起来你不需要从你的问题描述中找到它。

如果你需要添加/删除元素(与使用set不同来更新给定位置的元素,那么Peter Lawrey的方法是最好的。


相比之下,HashMap<Integer, Object>将是一个昂贵的选择。粗略估计,我会说“索引”操作的速度至少要慢10倍,与等效数组或ArrayList类型相比,数据结构需要10倍的空间。如果数组很大且稀疏,基于哈希表的解决方案实际上只是一种可行的替代方案(从性能角度来看)。

答案 1 :(得分:1)

有时您会无法获得索引。这需要您添加可能稍后填充的虚拟条目。

int indexToAdd = ...
E elementToAdd = ...

while(list.size() <= indexToAdd) list.add(null);
list.set(indexToAdd, elementToAdd);

这将允许您添加列表当前末尾之外的条目。


List.add(int, E)List.set(int, E)的Javadoc状态

  

IndexOutOfBoundsException - 如果索引超出范围(索引&lt; 0 || index&gt; size())

如果您尝试在结尾之外添加条目

List list = new ArrayList();
list.add(1, 1);

你得到了

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
    at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:612)
    at java.util.ArrayList.add(ArrayList.java:426)
    at Main.main(Main.java:28)

答案 2 :(得分:0)

我不确定HashMap<Integer, T>会有多贵。 Integer.hashCode()非常有效,尽管唯一非常昂贵的操作可能是随着项目数量的增加将数据复制到一个新的更大的数组中。但是,如果您知道自己的n,则可以使用普通数组

作为替代方案,您可以实现自己的Map<Integer, T>,它不使用哈希码,而是使用Integer本身。在此之前,请确保数组既不充分也不HashMap足够有效!

答案 3 :(得分:0)

我认为你至少有两个不错的选择。

第一种是使用初始化为适当长度的直接Java数组,然后使用语法添加对象:

    theArray[i] = object;

第二种方法是使用HashMap,并使用语法

添加对象
    theMap.put(i, object);

我不确定您担心哪些性能问题,但是在范围内添加元素,清除(从数组中删除)或删除(从HashMap中删除),以及从给定索引(或键)中查找元素对于HashMap,两个结构都是O(1)。如果这些看起来都不好,我还建议你看看Wikipedia's list of data structures