我有一个ArrayList,它从ArrayList的末尾(即使用方法add(object))以串行方式(即一对一)填充Integer类型的对象。每次我这样做时,ArrayList中的其他对象当然都会左移一个索引。
在我的代码中,我想在ArrayList中找到随机对象的索引。我想避免使用indexOf方法,因为我有一个很大的ArrayList并且循环将花费大量时间。有什么解决方法吗?一些想法如何保持某种数据结构,也许是ArrayList中对象的索引?
编辑:显然我的问题不清楚,或者我对arraylist.add(object)方法有误解(这也是很有可能的!)。我想要做的是像滑动窗口一样,将对象插入到arraylist的一端,然后将其从另一端放下,当对象插入一端时,其他对象移动一个索引。我可以使用arraylist.add(0,object)从arraylist的左边插入对象,并且每次将前一个对象右移一个索引,但是通过Google搜索,我发现这是非常耗费处理的操作- O(N),如果我没记错的话。因此,我认为“好吧,让我们从arraylist的右端插入对象,没问题!”,假设每次插入仍会将先前的对象移动一个索引(这次是向左移动)。
同样,当我使用术语“索引”时,我只是表示对象在ArrayList中的位置-也许还有一些更正式的术语“索引”,这意味着有所不同。
您有两种选择。这是两个基本选项:
您可以维护一个Map<Object,Integer>
与数组并行的索引。当您将元素添加到数组时,可以将其添加到地图中。从开头删除元素时,您将不得不遍历整个地图,并从每个索引中减去一个。
如果适合您的情况并且Map
不满足您的性能要求,则可以将一个index
字段添加到对象,并在将索引添加到数组时直接存储该索引。从开头删除元素时,您将必须遍历列表中的所有对象,并从其索引中减去一个。然后,您可以在给定对象的恒定时间内获取索引。
这些在删除后仍然具有更新索引的性能。现在,在选择以下选项之一之后,如果进行了简单的改进,就可以避免删除后在迭代地图/列表时进行更新:
与其存储每个对象的索引,不如存储到目前为止添加的对象总数的计数。然后,要获取实际索引,只需从您要查找的对象的值中减去第一个对象的计数值即可。例如,当您添加:
add a to end;
a.counter = counter++;
remove first object;
(counter
启动程序时的初始值并不重要。)然后找到对象“ x”:
index = x.counter - first object.counter;
是否将其存储counter
为新字段还是存储在地图中都取决于您。希望能有所帮助。
顺便说说; 从列表的最前面删除对象时,链表的性能会更好,但按索引访问对象时,链表的性能会更差。取决于您添加/删除与随机访问之间的平衡,它可能更合适(如果您只关心索引,但实际上从不需要按索引检索对象,则随机访问性能无关紧要)。如果确实需要进一步优化,则可以考虑使用固定容量的环形缓冲区(后插入,前删除和随机访问均为O(1))。
当然,选项3是在更高层次上重新考虑算法;也许有一种方法可以完成您要寻找的行为,而无需在列表中查找对象。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句