简体   繁体   English

Java:存储到ArrayList的任意索引的最佳方式

[英]Java: Best way to store to an arbitrary index of an ArrayList

I know that I cannot store a value at an index of an ArrayList that hasn't been used yet, ie is less than the size. 我知道我不能将值存储在尚未使用的ArrayList的索引处,即小于大小。 In other words, if myArrayList.size() is 5, then if I try to do 换句话说,如果myArrayList.size()为5,那么如果我尝试做的话

myArrayList.set(10, "Hello World") 

I will get an out of bounds error. 我会得到一个出界的错误。 But my app needs this. 但我的应用需要这个。 Other than a loop of storing null in each of the intermediate slots, is there a more elegant way? 除了在每个中间槽中存储null的循环之外,还有更优雅的方式吗?

It looks to me like: 它看起来像我:

  • This behavior is the same in Vector Vector中的行为相同
  • If I need to be able to randomly access (ie element at pos X) then my choices are Vector and ArrayList. 如果我需要能够随机访问(即在pos X处的元素),那么我的选择是Vector和ArrayList。
  • I could use a HashMap and use the index as a key but that's really inefficient. 我可以使用HashMap并将索引用作键,但这实在是效率低下。

So what is the elegant solution to what looks like a common case. 那么看起来像普通情况的优雅解决方案是什么呢? I must be missing something... 我肯定错过了什么...

I could use a HashMap and use the index as a key but that's really inefficient. 我可以使用HashMap并将索引用作键,但这实在是效率低下。

Depends. 要看。 If the indices you use are very sparse, it might be a lot better to use a Map. 如果您使用的索引非常稀疏,那么使用Map可能要好得多。 If the indices tend to be closely together, I think there is no better way than to fill it with nulls. 如果指数倾向于紧密相连,我认为没有比用空值填充它更好的方法了。 Just write a utility function for it that you can use over and over instead of repeating the loop everywhere you need it, something like this: 只需为它编写一个实用程序函数,您可以反复使用它,而不是在需要的地方重复循环,如下所示:

private void padTo(List<?> list, int size) {
    for (int i=list.size(); i<size; i++)
        list.add(null);
}

You can use a Map<Integer, MyClass> instead. 您可以使用Map<Integer, MyClass> Specifically, if you use HashMap , it will also be O(1) - though it will be slower than ArrayList . 具体来说,如果你使用HashMap ,它也将是O(1) - 虽然它会比ArrayList慢。

You can use TreeMap<key, value> , which is sorted in natural order by the value . 您可以使用TreeMap<key, value> ,这是由自然顺序排序value

Here you can keep value as the index. 在这里,您可以将值保留为索引。 You can insert any value, it need not be in order. 您可以插入任何值,它不需要按顺序排列。 This seems the simplest solution. 这似乎是最简单的解决方案。

Sounds like you want a regular array: 听起来你想要一个普通的数组:

  • You want random access 你想要随机访问
  • You want to specify some large size 您想指定一些大尺寸

If you definitely have to use the list and not a map, then it's best you override the arraylist's add and set methods to first put a null in indexes before. 如果你肯定要使用列表而不是地图,那么你最好覆盖arraylist的add和set方法,先在索引中放入null。 No other better way IMO 没有其他更好的方式IMO

HashMap is probably much less inefficient than you think, try it. HashMap的效率可能远低于您的想象,尝试它。 Otherwise, I can think of no way of doing it more elegantly than looping and filling with null. 否则,我认为没有办法比循环和填充null更优雅。 If you want elegance of exposition at least, then you could always subclass ArrayList and add an expandingSet(position, value) method to hide all the looping and such, or something. 如果你想要至少优雅的博览会,那么你总是可以继承ArrayList并添加一个expandingSet(position,value)方法来隐藏所有的循环等等。 Perhaps this isn't an option though? 也许这不是一个选择吗? If not just have a utility method somewhere else for it, but this is not as nice imho, though it will work also with other types of list too I guess... 如果不只是在其他地方有一个实用工具方法,但这不是很好的imho,虽然它也适用于其他类型的列表我猜...

Perhaps a wrapper class would be the best of both worlds, or perhaps it would just incur unnecessary overhead... 也许包装类可能是两个世界中最好的,或者它可能会产生不必要的开销......

If you are looking for a sparse array (where most of the indices will be empty), a Map of some sort (probably a HashMap) will be your best bet. 如果您正在寻找稀疏数组(其中大多数索引将为空),那么某种类型的地图(可能是HashMap)将是您最好的选择。 Any array-esque solution will be forced to reserve space for all the empty indices, which is not very space-efficient, and a HashMap is fast enough for most normal purposes. 任何阵列式解决方案都将被强制为所有空索引保留空间,这不是非常节省空间,并且HashMap足够快以用于大多数正常目的。

If you will eventually fill up the array up to some n, you will need to add nulls in a loop to get to the index you want. 如果最终将数组填满n,则需要在循环中添加空值以获得所需的索引。 You can make this somewhat more efficient by giving it an initial capacity of the number of elements you will eventually want to store (this prevents the ArrayList from needing to resize itself). 您可以通过为其最终要存储的元素数量的初始容量来提高效率(这可以防止ArrayList需要自行调整大小)。 new ArrayList(n) will work fine. new ArrayList(n)可以正常工作。 Unfortunately, there is no simple way of making it a certain size to begin with except adding things in a loop when you make it. 不幸的是,除了在制作循环时添加内容之外,没有简单的方法可以使它开始具有一定的大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM