我有一个ArrayList,我从ArrayList的末尾(即使用add(object)方法)以串行方式(即逐个)填充Integer类型的对象。每次执行此操作时,ArrayList中的其他对象当然会被一个索引左移。
在我的代码中,我想在ArrayList中找到随机对象的索引。我想避免使用indexOf方法,因为我有一个非常大的ArrayList,循环将花费大量的时间。有没有解决方法?有些想法如何在某些数据结构中保留ArrayList中对象的索引?
编辑:显然我的问题不明确,或者我对arraylist.add(对象)方法有误解(这也很有可能!)。我想做的是有一个类似滑动窗口的东西,其中对象被插入到arraylist的一端并从另一端掉落,并且当一个对象插入到一端时,其他对象被移动一个索引。我可以使用arraylist.add(0,object)从arraylist的左边插入对象,每次将前一个对象右移一个索引,但是进行谷歌搜索我发现这是一个非常耗费处理的操作 - O(N)如果我没记错的话。因此,我认为“好吧,让我们从arraylist的右端插入对象,没问题!”,假设仍然每次插入都会将前一个对象移动一个索引(这次是向左)。当我使用术语“索引”时,我只是指对象在ArrayList中的位置 - 也许还有一些更为完整的术语“索引”,这意味着不同的东西。
答案 0 :(得分:4)
你有几个选择。以下是两个基本选项:
您可以与数组并行维护保存索引的Map<Object,Integer>
。将元素追加到数组时,只需将其添加到地图即可。当您从头开始删除元素时,您将不得不遍历整个地图并从每个索引中减去一个。
如果它适合您的情况且Map
不符合您的性能要求,您可以在对象中添加index
字段,并在将索引添加到对象时直接存储索引阵列。从头开始删除元素时,必须遍历列表中的所有对象并从索引中减去一个对象。然后,您可以在给定对象的恒定时间内获取索引。
这些仍然会在删除后更新索引。现在,在您选择其中一个选项后,如果您进行了简单的改进,则可以避免在删除后迭代地图/列表进行更新:
不存储每个对象的索引,而是存储到目前为止添加的对象总数的计数。然后,要获取实际索引,只需从您要查找的值的值中减去第一个对象的计数值。例如。当你添加:
add a to end;
a.counter = counter++;
remove first object;
(启动程序时counter
的初始值并不重要。)然后找到一个对象“x”:
index = x.counter - first object.counter;
您是将counter
存储为新字段还是存储在地图中取决于您自己。希望有所帮助。
当然,选项3是在更高级别重新考虑您的算法;也许有一种方法可以完成你正在寻找的行为,而不需要在列表中找到对象。