【问题标题】:Calculating difference of two lists with duplicates计算两个重复列表的差异
【发布时间】:2018-08-30 20:15:46
【问题描述】:

我有两个列表。

List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 2));
List<Integer> list2 = new ArrayList<>(Arrays.asList(2, 3, 4));

我想从list1 中删除list2 中包含的元素,删除次数与它们在list2 中包含的次数一样多。在上面的示例中:当我们删除列表 1 中存在于列表 2 中的元素时,我们应该得到 [1, 2] 的结果(2 应该从 list1 中删除一次,因为 list2 只包含一个实例2)。

我尝试使用list1.removeAll(list2);,但结果列表仅包含[1]

实现这一目标的最佳方法是什么?同时遍历两个列表对我来说似乎有点难看。

【问题讨论】:

  • "1 和 2 而不仅仅是 1" - 我不明白,你能发布结果列表吗?
  • 人们被否决的方式在这里是不公平的。你只是关闭这个问题,因为它没有很好地表述.. 它需要更清楚地解释。
  • @arthur:对不完全理解问题的答案投反对票是有意义的。根据定义,与问题无关的答案是错误
  • @arthur 否决不正确的答案到底是什么不公平?例如,starman1979 提供的答案与list1.removeAll(list2); 完全相同,所以 OP 目前使用的是什么。 higz555 提供的答案基本上从​​每个列表中删除了重复项,但这似乎也不是 OP 想要的。
  • “拒绝投票应该保留在极端情况下。它不能代替沟通和编辑。” stackoverflow.com/help/privileges/vote-down

标签: java arraylist iterator java-stream


【解决方案1】:

如果我理解正确,您只想从 list1 中删除单个 2 元素,而不是全部删除。您可以遍历list2 并尝试从list1 中删除每个元素。请记住,如果list2 不能包含重复项,还有比这更有效的方法。

var list1 = new ArrayList<>(List.of(1, 2, 2));
var list2 = List.of(2, 3, 4);

list2.forEach(list1::remove);    

list1 现在包含以下内容:

[1, 2]

请参阅starman1979's answer 以获得相同的解决方案,但使用的是 lambda 而不是方法引用。

【讨论】:

  • 你能解释一下为什么这比@starman1979 的建议更好吗?
  • +1 向我们展示了varmedium.com/@afinlay/…
  • @jschnasse 在发布我的答案之前我什至没有看到他们的答案,但他们的答案看起来是正确的。我不知道为什么它被否决了。
  • @Pshemo List#removeAlllist1 中删除包含在list2 中的所有元素(不仅仅是一个)。
  • @Pshemo list.removeAll(other) 类似于list.removeIf(other::contains) 而这个解决方案是other.forEach(list::remove)。它们之间的区别正是问题所在。
【解决方案2】:

怎么样:

list2.forEach(i -> {
    list1.remove(i); //removes only first occurrence - if found
});

list1 现在包含

[1, 2]

【讨论】:

  • 你的解决方案和OP有什么区别?
  • +1 表示第一次尝试并至少提供所需的结果。 @Pshemo 如果投反对票,也许会想出一个更优雅的解决方案?
  • @jschnasse 好的,我错了。没有注意到remove 仅删除 first 出现的指定元素,而不是 all 的事实。但这也是我在这里发表第一条评论的原因。答案不应该只包含解决方案,问题的解释和描述解决方案如何/为什么解决它也很重要。
  • 很遗憾,除非答案将被编辑,否则我无法更改我的投票(而且我不会投票,除非它包含一些解释为什么/如何解决问题)。
  • 对不起,伙计们,应该详细说明一下。
【解决方案3】:

给定

List<Integer> a = new ArrayList<>(Arrays.asList(1, 2, 2));
List<Integer> b = Arrays.asList(2, 3, 4);

使用以下变体之一来获得所需的结果:

1.纯java

b.forEach((i)->a.remove(i));

a 现在包含

[1, 2]

在原帖上注明:add +1:

2。 Apache Commons

apache commons 中有一个subtract 方法

Collection<Integer> result = CollectionUtils.subtract(a, b);

result 现在包含

[1, 2]

这里是how they implemented it

3.番石榴

由于 guava 不提供 subtract 方法,您可能会发现 this advice from the google implementors 很有帮助

"创建一个包含 a 的 ArrayList,然后对 b 中的每个元素调用 remove。"

这基本上呈现在 1.

中已经提到的内容

【讨论】:

    猜你喜欢
    • 2021-05-04
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2011-09-23
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多