比较两个非常大的列表的最佳方法

时间:2017-08-19 11:20:51

标签: java performance list collections comparison

我有两个非常大的名单。让我们说几百万元素。两个列表已经以相同的方式排序。现在我需要检查两个列表是否相等。 做这个的最好方式是什么? 现在我的想法是使用Assert.assertEquals比较行到行。

for(int i=0;i<Math.max(list1.size(),list2.size()),i++){

Assert.assertEquals(list1.get(i),list2.get(i));
}

不幸的是,如果列表中有数百万个对象,我会担心此解决方案的性能。此外,如果列表不相等,那么我需要知道差异在哪里。

有没有更好,更快,更自信的解决方案呢?

5 个答案:

答案 0 :(得分:3)

如果列表相同,最后它会进行O(n)操作。所以我会简单地使用:

Assert.assertEquals(list1, list2);

将依赖List::equals来比较列表 - 我怀疑你可以比这更有效率,除非你有关于列表内容的具体信息。

如果列表不相等,您应该得到一个显示差异的异常。

答案 1 :(得分:1)

更简单的方法是使用您无论如何使用的列表大小:

if(list1.size() > list2.size()) {
    list1.removeAll(list2);
    // print the list1 (discrepancies)
    Assert.fail("Lists are not equal");
} else if
...// same for list2.size() > list1.size()
} else {
    list1.removeAll(list2);
     if(!list1.isEmpty()) { 
        // print the discrepancies
        Assert.fail("Lists are not equal");
     } 
}

答案 2 :(得分:1)

性能主要取决于您将用于执行它的Collection 方法

正如您提到的代码,它是使用 get 列表方法进行迭代和比较,我们需要知道实现列表的哪个集合类具有更好的 get 性能方法..

for(int i=0;i<Math.max(list1.size(),list2.size()),i++){
    Assert.assertEquals(list1.get(i),list2.get(i));
}

如果您使用列表实施的 LinkedList 获取方法,那么获取单个对象的效果顺序将 O(n / 4)平均值

如果您使用列表实施 ArrayList get方法,则获取单个对象的效果顺序将为 O(1)

因此,我们可以说基于您的代码的比较对于 ArrayList 会更快。

答案 3 :(得分:1)

这很简单:当你想确定两个列表相等时 - 你必须按元素进行比较。当然,只有当两个列表具有相同的大小时才会这样做。

因此你总是处理O(n)。

Java ArrayLists已经是数据结构的不错选择。

唯一潜在的优化:通过使用多个线程比较子列表可以更快地解决此问题。所以parallelStream()可能是你的朋友。

或者 - 当列表包含int,double ...原始值时 - 那么您可以考虑使用普通旧数组而不是基于集合的列表。

答案 4 :(得分:0)

您应该将它们存储在二叉树中。与列表相比,搜索速度非常快。