我有两个大的(超过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 (或其他一些列表))
答案 0 :(得分:9)
是的,对于大量数字,HashMap
是有益的。
您的初始算法将花费很长时间,在嵌套的for循环中遍历两个列表。这是O(n 2 )算法。即使假设A
和B
中每个都有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
建造成本。