【问题标题】:The best way to compare two very large lists比较两个非常大的列表的最佳方法
【发布时间】:2017-08-19 11:20:50
【问题描述】:

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

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

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

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

有没有更好、更快、更有信心的解决方案来做到这一点?

【问题讨论】:

  • 是ArrayList还是LinkedList?
  • @RajuSharma 数组列表

标签: java performance list collections comparison


【解决方案1】:

如果列表相等,最后它是一个 O(n) 操作。所以我会走简单的路,简单地使用:

Assert.assertEquals(list1, list2);

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

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

【讨论】:

  • 如果列表不相等,您应该得到一个显示差异的异常。聪明聪明:)
  • 在众多答案中,唯一一个真正有意义的答案(恕我直言)。
  • 缺少的一件事......您可能想提及使断言工作所需的先决条件。 OP 可能不需要,但未来的读者可能不需要。
  • 不明白你的意思,什么前提条件?
【解决方案2】:

执行此操作的更简单方法是调整列表的大小,无论如何您都在使用:

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");
     } 
}

【讨论】:

  • 他主要是问性能。您的代码在幕后做了很多事情。不确定这有多大帮助。
【解决方案3】:

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

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

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

如果您使用 List 实现的 LinkedList get 方法,那么获取单个对象的性能顺序将是 O(n/4) 平均.

如果您使用 List 实现的 ArrayList get 方法,那么获取单个对象的性能顺序将是 O(1)

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

【讨论】:

  • ArrayList get 方法,那么性能顺序将是 O(1)。 总体而言?
  • @nullpointer 是的,实现 ArrayList 的 List 的 get 方法会比实现 LinkedList 的 List 有更好的性能
  • 这里不讨论比较,但整体顺序不会是O(1),即使我们在ArrayList 上执行get
  • @nullpointer,我说的是单次提取.. 我确实修改了相同的
【解决方案4】:

这很简单:当你想确保两个列表相等时——你必须逐元素比较它们。当然,只有在两个列表大小相同时才这样做。

因此,您总是处理 O(n)。

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

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

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

【讨论】:

    【解决方案5】:

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

    【讨论】:

    • 废话。他在问如何有效地比较两个大列表。把它们变成树根本没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 2017-08-17
    • 2017-05-02
    相关资源
    最近更新 更多