Java:存储到 ArrayList 的任意索引的最佳方法
我知道我无法在尚未使用的 ArrayList 索引处存储值,即小于大小。换句话说,如果 myArrayList.size() 是 5,那么如果我尝试这样做,
myArrayList.set(10, "Hello World")
我将收到越界错误。但我的应用程序需要这个。除了在每个中间槽中存储 null 的循环之外,还有更优雅的方法吗?
在我看来:
- 这种行为在 Vector 中是相同的。
- 如果我需要能够随机访问(即 pos X 处的元素),那么我的选择是 Vector 和 ArrayList。
- 我可以使用 HashMap 并使用索引作为键,但这确实效率很低。
那么对于看似常见的情况,优雅的解决方案是什么?我一定是错过了什么……
I know that I cannot store a value at an index of an ArrayList that hasn't been used yet, i.e. is less than the size. In other words, if myArrayList.size() is 5, then if I try to do
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?
It looks to me like:
- This behavior is the same in Vector
- If I need to be able to randomly access (i.e. element at pos X) then my choices are Vector and ArrayList.
- I could use a HashMap and use the index as a key but that's really inefficient.
So what is the elegant solution to what looks like a common case. I must be missing something...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用
Map
来代替。具体来说,如果您使用HashMap
,它也将是O(1)
- 尽管它会比ArrayList
慢。You can use a
Map<Integer, MyClass>
instead. Specifically, if you useHashMap
, it will also beO(1)
- though it will be slower thanArrayList
.听起来你想要一个常规数组:
Sounds like you want a regular array:
如果您确实必须使用列表而不是映射,那么最好重写 arraylist 的 add 和 set 方法,以便首先在索引中添加 null。 IMO没有其他更好的方法
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. No other better way IMO
HashMap 的效率可能比你想象的要低得多,试试吧。否则,我想不出比循环和填充 null 更优雅的方法了。如果你至少想要优雅的阐述,那么你总是可以继承 ArrayList 并添加一个 ExpandingSet(position, value) 方法来隐藏所有循环等。也许这不是一个选择?如果不只是在其他地方有一个实用方法,但这并不那么好,恕我直言,尽管它也适用于其他类型的列表,我猜......
也许包装类将是两全其美的,或者也许它只会产生不必要的开销......
HashMap is probably much less inefficient than you think, try it. Otherwise, I can think of no way of doing it more elegantly than looping and filling with 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. 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...
Perhaps a wrapper class would be the best of both worlds, or perhaps it would just incur unnecessary overhead...
如果您正在寻找稀疏数组(其中大多数索引为空),某种 Map(可能是 HashMap)将是您最好的选择。任何数组式的解决方案都将被迫为所有空索引保留空间,这不太节省空间,而 HashMap 对于大多数正常用途来说足够快。
如果您最终将数组填充到某个 n,则需要在循环中添加空值以获取所需的索引。您可以通过为其指定最终要存储的元素数量的初始容量(这可以防止 ArrayList 需要调整自身大小)来提高效率。
new ArrayList(n)
可以正常工作。不幸的是,除了在制作时在循环中添加内容之外,没有简单的方法可以使其一开始就达到一定的大小。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. 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.
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. 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).
new ArrayList(n)
will work fine. 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.视情况而定。如果您使用的索引非常稀疏,那么使用 Map 可能会更好。如果索引往往紧密相连,我认为没有比用空值填充更好的方法了。只需为其编写一个实用函数,您可以反复使用它,而不是在需要的地方重复循环,如下所示:
Depends. If the indices you use are very sparse, it might be a lot better to use a 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:
您可以使用
TreeMap
,它按value
按自然顺序排序。这里你可以保留价值作为索引。您可以插入任何值,无需按顺序排列。这似乎是最简单的解决方案。
You can use
TreeMap<key, value>
, which is sorted in natural order by thevalue
.Here you can keep value as the index. You can insert any value, it need not be in order. This seems the simplest solution.