比较两个不等大小的arraylists - 堆问题比较

时间:2014-11-07 22:02:46

标签: java sorting arraylist collections

我将两个arraylist<String>与列表一的平均大小50K和列表二200K进行比较。

int size = MsSQLList.size();

for (int index = 0; index < size; index++) {
    if (!oracleSQLList.contains(MsSQLList.get(index))) {                        
        logger.debug(" *[POSSIBLE MISS]* Oracle missing record id: "
                       + (MsSQLList.get(index)));
    }
}

列表中的数据字符串为16个字符,即A89EERDD12312445等...我在进入上述循环之前在两者上运行Collection.sort(list)

平均比较时间接近160秒。这是最好的方法还是我们可以做得更好?

问题2: 您猜到的结果是从DB获取的,持续5天。

如果我选择30天作为我的间隔,理想情况下我可以获得110万条记录。由于此负载,旧数组列表实现抛出OutofMemory。

因此,快速跟进问题我现在可以将负载推回到110万,间隔30天吗?

3 个答案:

答案 0 :(得分:2)

如果值是唯一的,请将它们放在Set s而不是数组列表中。

假设你有

Set<String> oracleSet = new HashSet<>();
Set<String> msSet = new HashSet<>();

然后在填写之后,您可以使用

msSet.removeAll(oracleList);

然后,如果msSet.isEmpty()返回false,您知道msSet中的项目oracleSet中不存在。{1}}。如果您愿意,可以通过迭代msSet来打印它们。

当然,如果你需要保留msSet以便在删除之前继续工作,请使用它的副本:

Set<String> copyOfMsSet = new HashSet<>( msSet );

并使用copyOfMsSet.removeAll(oracleList)代替msSet.removeAll(oracleList)

如果您不需要订购商品,

HashSet搜索效率非常高。如果你这样做,你应该使用TreeSet,但效率会降低。请注意,效率取决于设置的容量和负载系数(可以在构造函数中设置),这可能会影响非常大的集合的性能。

如果oracleSetmsSet大得多,那么做这样的事情会更有效率:

Set <String> intersectionOfMsAndOracleSets = new HashSet<>( msSet );
intersectionOfMsAndOracleSets.retainAll( oracleSet );

然后

msSet.removeAll( intersectionOfMsAndOracleSets );

也就是说,假设msSet的大小为noracleSet的大小为mn远小于m然后交集的操作需要O(n),而我的原始建议是O(m)。如果m大约是n的四倍,则会变得更有效率。

答案 1 :(得分:2)

你最大的问题是contains()是O(n),因为它只是遍历列表直到它被命中(平均迭代次数为n / 2),这当然表现不佳。

此外,对列表进行排序对性能没有任何帮助。

卑微的HashSet是你的朋友:它具有O(1)所有操作的表现。

使用集合还可以在几行中完成所有操作:

Set<String> set = new HashSet<>(oracleSQLList);
for (String s : MsSQLList)
    if (!set.contains(s))                  
        logger.debug(" *[POSSIBLE MISS]* Oracle missing record id: " + s);

上述代码应该在几分之一秒内完成。

答案 2 :(得分:1)

因为你有你的列表排序,你可以做二次复杂度,你可以使用线性方法

for (int i=0,j=0;i<MsSQLList.size();i++){
            if (j>=oracleSQLList.size() || !MsSQLList.get(i).equals(oracleSQLList.get(j))){
                 logger.debug(" *[POSSIBLE MISS]* Oracle missing record id: "
                   + (MsSQLList.get(index)));
            }else{
                j++;
            }

        }

但同样,你的瓶颈将是排序,除非你能在数据库中做到这一点