我正在尝试找出用于我的情况的数据结构。我正在寻找的内容非常(非常)类似于ArrayList
,除了Java ArrayList
抛出IndexOutOfBoundsException
"如果索引>尺寸()"
我会知道插入的每个项目的索引,但我不知道总容量(排除一般数组),也不会按排序顺序接收项目。
基本上,我可以用什么来保持这个:
| 1 | 2 | 3 | 4 | 5 | 6 | ... |
| Item3 | --- | Item1 | Item6 | --- | Item3 | |
(新插入)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| Item3 | --- | Item1 | Item6 | --- | Item3 | --- | Item7 | <--- This would throw `IndexOutOfBoundsException` in Java
(新插入)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| Item3 | --- | Item1 | Item6 | Item2 | Item3 | --- | Item7 |
等...
编辑:插入空值的建议很好。我可能会走那条路。但仅仅是为了记录,ArrayList::ensureCapacity
不足以增加&#34;尺寸&#34; ArrayList
,只有容量。拿这个代码:
ArrayList list = new ArrayList();
list.ensureCapacity(10);
list.add(5, "Five");
抛出这个:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 0
at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:643)
at java.util.ArrayList.add(ArrayList.java:455)
at test4.Test18.main(Test18.java:20)
当&#34;尺寸&#34;是0,唯一可接受的索引是&#39; 0&#39;。当大小为1时,您可以在0或1处插入。我确定这是以这种方式实现ArrayList
的充分理由,但我无法看到。
答案 0 :(得分:4)
在访问索引之前,只需适当调整数组大小:
while (list.size() < index + 1)
list.add(null);
list.set(index, value);
如果你写的是“未来”,你可以另外在循环之前使用list.ensureCapacity(index + 1)
,但这最好是一个恒定因子优化。无论如何,运行时是 O(N),其中 N 是您在算法执行期间访问的最高索引。
当然,如果您的数据集稀疏且大部分插槽在所有操作完成后仍为空,则该方法将浪费空间。在这种情况下,请考虑使用哈希表而不是数组(Java中的HashMap<Integer, T>
)。
答案 1 :(得分:2)
使用Map<Integer, Item>
。
HashMap
非常适合用作稀疏数组。如果你需要维护迭代顺序,那么TreeMap
会起作用,但计算成本会更高。
对于HashMap
,保证put
和get
O(1)
。
对于TreeMap
,保证put
和get
O(lg n)
。
如果元素不存在,Map
将永远不会抛出异常 - 您将返回null
。
如果您只有Map
的元素和1000
的元素,则无需将0
的大小增加到999
。尺寸仅为2
。