我知道我不能将值存储在尚未使用的ArrayList的索引处,即小于该大小。换句话说,如果myArrayList.size()为5,那么如果我尝试
myArrayList.set(10, "Hello World")
我会得到一个越界错误。但我的应用需要这个。除了在每个中间槽中存储null的循环之外,还有更优雅的方法吗?
在我看来:
那么看起来像普通情况的优雅解决方案是什么呢?我一定错过了什么......
答案 0 :(得分:4)
我可以使用HashMap并将索引用作键,但效率非常低。
取决于。如果您使用的索引非常稀疏,那么使用Map可能要好得多。如果指数倾向于紧密相连,我认为没有比用空值填充它更好的方法了。只需为它编写一个实用程序函数,您可以反复使用它,而不是在需要的地方重复循环,如下所示:
private void padTo(List<?> list, int size) {
for (int i=list.size(); i<size; i++)
list.add(null);
}
答案 1 :(得分:3)
您可以使用Map<Integer, MyClass>
代替。具体来说,如果您使用HashMap
,它也会O(1)
- 虽然它会比ArrayList
慢。
答案 2 :(得分:3)
您可以使用TreeMap<key, value>
,value
按自然顺序排序。
您可以将值保留为索引。您可以插入任何值,它不需要按顺序排列。这似乎是最简单的解决方案。
答案 3 :(得分:1)
听起来你想要一个普通的数组:
答案 4 :(得分:1)
如果你肯定必须使用列表而不是地图,那么你最好覆盖arraylist的add和set方法,先在索引中放入null。没有其他更好的方式IMO
答案 5 :(得分:1)
HashMap可能效率低于您的想法,尝试它。否则,我认为没有办法比循环和填充null更优雅。如果你想要至少优雅的博览会,那么你总是可以继承ArrayList并添加一个expandingSet(position,value)方法来隐藏所有的循环等等。也许这不是一个选择吗?如果不只是在其他地方有一个实用工具方法,但这不是很好的imho,虽然它也适用于其他类型的列表我猜...
也许包装类可能是两个世界中最好的,或者它可能会产生不必要的开销......
答案 6 :(得分:0)
如果您正在寻找一个稀疏数组(其中大多数索引都是空的),某种类型的地图(可能是HashMap)将是您最好的选择。任何阵列式解决方案都将被强制为所有空索引保留空间,这不是非常节省空间,并且HashMap足够快以用于大多数正常目的。
如果最终将数组填满n,则需要在循环中添加空值以获取所需的索引。您可以通过为其最终要存储的元素数量的初始容量来提高效率(这可以防止ArrayList需要自行调整大小)。 new ArrayList(n)
可以正常使用。不幸的是,除了在制作循环时添加内容之外,没有简单的方法可以使它开始具有一定的大小。