性能:遍历ArrayList数百次,而不是将Arraylist转换为HashMap然后返回?

时间:2019-05-28 23:18:36

标签: java performance arraylist hashmap

我有两个大的(超过1000个对象)ArrayList需要比较和操作。我本质上需要从ArrayList A中获取一个值,在ArrayList B中查找匹配的对象,然后从B中操作该对象。我需要在A的所有对象中执行此操作。我需要在应用程序中经常执行此操作。订单未知,大小会有所不同。

(pseudocode)
ArrayList<myObject> A
ArrayList<myObject> B

对于A中的每个实体,我都可以遍历B中的每个单个项目,寻找与A中的实体相匹配的项目。这似乎效率很低。

(pseudocode)
for (each object in A){loop through all of B and find it}

将B转换为HashMap(使用我正在比较的特定值作为键,将对象作为值),然后以这种方式搜索B,然后在我将临时HashMap转换回ArrayList时,是否值得?完成处理了吗?

(pseudocode)
convert B to HashMap<myObject.myValue,myObject> C
for (each object in A){look up the value in C}
convert C back to an ArrayList

这是个好主意吗?还是这种过早/不必要的优化?谢谢。

(背景:数据从服务中以ArrayList的形式传给我-前端需要用于视图层的ArrayList。我试图使中间层处理更有效-但入口和出口对象必须是ArrayList (或其他一些列表))

1 个答案:

答案 0 :(得分:9)

是的,对于大量数字,HashMap是有益的。

您的初始算法将花费很长时间,在嵌套的for循环中遍历两个列表。这是O(n 2 )算法。即使假设AB中每个都有1000个项目,并且假设比较两个单独项目(一项来自A和一项来自B)的成本为1,进行500k比较(避免将每个项目进行两次比较)。经常这样做会导致性能降低。

假设您的对象具有良好的哈希码算法,则从HashMap查找值就是O(1)访问。您仍然会花费O(n)的时间来构建它,但是与O(n 2 )相比,这没什么。

只要HashMap的信息没有改变,就使用“ B”中的数据构造一次B“ C”并多次使用。如果您“需要经常执行此操作”,则性能会更好,因为HashMap已经建立了,只需重用即可。

如果需要维护顺序,请将B列表索引存储为哈希图中的值。

您不需要“将临时哈希图转换回数组列表”,因为创建HashMap“ C”不会破坏原始列表“ B”。要注意的一件事是列表B中的对象是否更改,从而迫使对HashMap的更新保持一致。要注意的另一件事是您对非常大的列表的内存使用情况–您可以将对象,列表和哈希图保留在内存中吗?

您的伪代码:

for each index in B:
    get object b
    put in hash map C values (b, index)

for each a in A:
    if found in hash map C: do something with found object

对于较小的数字,O(n 2 )的性能时间将足够短,以至于构建HashMap是不值得的。这是您需要做出的决定-您需要确定列表何时足够大,以至于建造HashMap并值得HashMap建造成本。