如何最好地比较Java中的两个集合并采取行动?

2022-09-01 02:03:08

我有同一对象的两个集合,并且.所需的逻辑如下所示:Collection<Foo> oldSetCollection<Foo> newSet

  • 如果 是 in(*) 但不是 ,则调用foooldSetnewSetdoRemove(foo)
  • 否则,如果不是,而是在 中,则调用foooldSetnewSetdoAdd(foo)
  • else 如果 位于两个集合中但已修改,则调用foodoUpdate(oldFoo, newFoo)
  • 否则 如果 ,则调用!foo.activated && foo.startDate >= nowdoStart(foo)
  • 否则 如果 ,则调用foo.activated && foo.endDate <= nowdoEnd(foo)

(*)“in”表示唯一标识符匹配,而不一定是内容。

当前(遗留)代码会进行许多比较,以找出 、 、 和 ,然后循环对每个项目执行操作。removeSetaddSetupdateSetstartSetendSet

代码非常混乱(部分原因是我已经省略了一些意大利面条逻辑),我正试图重构它。更多背景信息:

  • 据我所知,和 实际上由oldSetnewSetArrayList
  • 每组包含少于 100 个项目,最有可能在 20 个时最多包含 20 个项目
  • 此代码经常被调用(以百万/天为单位),尽管集合很少不同

我的问题:

  • 如果我将 ID 作为键进行转换和转换(此处不关注顺序),是否会使代码更易于阅读和比较?转换会损失多少时间和内存性能?oldSetnewSetHashMap<Foo>
  • 迭代这两个集合并执行适当的操作是否会更有效和简洁?

答案 1

Apache的commons.collections库有一个CollectionUtils类,它为集合操作/检查提供了易于使用的方法,例如交集,差异和并集。

org.apache.commons.collections.CollectionUtils API docs 在这里


答案 2

您可以使用 Java 8 流,例如

set1.stream().filter(s -> set2.contains(s)).collect(Collectors.toSet());

或 来自番石榴的套装类:

Set<String> intersection = Sets.intersection(set1, set2);
Set<String> difference = Sets.difference(set1, set2);
Set<String> symmetricDifference = Sets.symmetricDifference(set1, set2);
Set<String> union = Sets.union(set1, set2);