在ArrayList中查找对象索引的有效方法

时间:2014-02-23 21:19:34

标签: java arraylist

我有一个ArrayList,我从ArrayList的末尾(即使用add(object)方法)以串行方式(即逐个)填充Integer类型的对象。每次执行此操作时,ArrayList中的其他对象当然会被一个索引左移。

在我的代码中,我想在ArrayList中找到随机对象的索引。我想避免使用indexOf方法,因为我有一个非常大的ArrayList,循环将花费大量的时间。有没有解决方法?有些想法如何在某些数据结构中保留ArrayList中对象的索引?

编辑:显然我的问题不明确,或者我对arraylist.add(对象)方法有误解(这也很有可能!)。我想做的是有一个类似滑动窗口的东西,其中对象被插入到arraylist的一端并从另一端掉落,并且当一个对象插入到一端时,其他对象被移动一个索引。我可以使用arraylist.add(0,object)从arraylist的左边插入对象,每次将前一个对象右移一个索引,但是进行谷歌搜索我发现这是一个非常耗费处理的操作 - O(N)如果我没记错的话。因此,我认为“好吧,让我们从arraylist的右端插入对象,没问题!”,假设仍然每次插入都会将前一个对象移动一个索引(这次是向左)。

当我使用术语“索引”时,我只是指对象在ArrayList中的位置 - 也许还有一些更为完整的术语“索引”,这意味着不同的东西。

1 个答案:

答案 0 :(得分:4)

你有几个选择。以下是两个基本选项:

  1. 您可以与数组并行维护保存索引的Map<Object,Integer>。将元素追加到数组时,只需将其添加到地图即可。当您从头开始删除元素时,您将不得不遍历整个地图并从每个索引中减去一个。

  2. 如果它适合您的情况且Map不符合您的性能要求,您可以在对象中添加index字段,并在将索引添加到对象时直接存储索引阵列。从头开始删除元素时,必须遍历列表中的所有对象并从索引中减去一个对象。然后,您可以在给定对象的恒定时间内获取索引。

  3. 这些仍然会在删除后更新索引。现在,在您选择其中一个选项后,如果您进行了简单的改进,则可以避免在删除后迭代地图/列表进行更新:

    不存储每个对象的索引,而是存储到目前为止添加的对象总数的计数。然后,要获取实际索引,只需从您要查找的值的值中减去第一个对象的计数值。例如。当你添加:

    add a to end;
    a.counter = counter++;
    remove first object;
    

    (启动程序时counter的初始值并不重要。)然后找到一个对象“x”:

    index = x.counter - first object.counter;
    

    您是将counter存储为新字段还是存储在地图中取决于您自己。希望有所帮助。

    顺便说一下;从列表前面删除对象时,链接列表将具有更好的性能,但在通过索引访问对象时更糟。根据您的添加/删除与随机访问的平衡可能更合适(如果您只关心索引但实际上从不需要通过索引检索对象,则随机访问性能无关紧要)。如果你真的需要进一步优化,可以考虑使用固定容量的环形缓冲区(后插入,前移除和随机访问都是O(1))。

    当然,选项3是在更高级别重新考虑您的算法;也许有一种方法可以完成你正在寻找的行为,而不需要在列表中找到对象。