欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > Java集合操作:如何正确计算两个集合的差集

Java集合操作:如何正确计算两个集合的差集

2025/4/19 15:58:14 来源:https://blog.csdn.net/m0_70590680/article/details/144528204  浏览:    关键词:Java集合操作:如何正确计算两个集合的差集

在 Java 中,计算两个集合的差集是一个常见的操作。然而,在实际开发中,我们常常需要的不仅是简单的差集,还可能是两个集合的对称差。对称差指的是集合 A 中独有的元素集合 B 中独有的元素的组合。本文将介绍几种实现对称差的方式,并提供代码示例。


什么是对称差?

给定两个集合:

  • 集合1: {1, 2, 3, 4}
  • 集合2: {2, 3, 4}

两者的对称差是:{1}


实现方法

方法 1:使用 removeAll 两次实现对称差

removeAll 是 Java 集合的基础方法,用于移除一个集合中与另一个集合相同的元素。通过两次 removeAll,分别计算集合 1 和集合 2 的差集,再将结果合并。

import java.util.HashSet;
import java.util.Set;public class SymmetricDifferenceExample {public static void main(String[] args) {Set<Integer> set1 = new HashSet<>();set1.add(1);set1.add(2);set1.add(3);set1.add(4);Set<Integer> set2 = new HashSet<>();set2.add(2);set2.add(3);set2.add(4);// 计算对称差Set<Integer> difference = new HashSet<>(set1);difference.removeAll(set2); // set1 中独有的元素Set<Integer> temp = new HashSet<>(set2);temp.removeAll(set1); // set2 中独有的元素difference.addAll(temp); // 合并结果System.out.println("对称差: " + difference); // 输出: 对称差: [1]}
}

方法 2:使用 Java 8 的流式操作

流式操作(Stream)提供了更优雅的方式来处理集合操作。通过 filter 筛选条件,可以高效实现对称差。

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class SymmetricDifferenceExample {public static void main(String[] args) {List<Integer> list1 = Arrays.asList(1, 2, 3, 4);List<Integer> list2 = Arrays.asList(2, 3, 4);// 使用流计算对称差Set<Integer> difference = Stream.concat(list1.stream().filter(item -> !list2.contains(item)),list2.stream().filter(item -> !list1.contains(item))).collect(Collectors.toSet());System.out.println("对称差: " + difference); // 输出: 对称差: [1]}
}

方法 3:使用 Guava 的 Sets.symmetricDifference

如果项目中已引入 Google Guava 库,可以直接调用 Sets.symmetricDifference 方法,它是专门为计算对称差设计的。

Maven 依赖

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.0.1-jre</version>
</dependency>

代码示例

import com.google.common.collect.Sets;
import java.util.Set;
import java.util.HashSet;public class SymmetricDifferenceExample {public static void main(String[] args) {Set<Integer> set1 = new HashSet<>();set1.add(1);set1.add(2);set1.add(3);set1.add(4);Set<Integer> set2 = new HashSet<>();set2.add(2);set2.add(3);set2.add(4);// 使用 Guava 计算对称差Set<Integer> difference = Sets.symmetricDifference(set1, set2);System.out.println("对称差: " + difference); // 输出: 对称差: [1]}
}

方法 4:手动遍历实现对称差

如果不使用高级库或 Java 8 特性,可以通过手动遍历集合来实现对称差。这种方法在某些场景下更容易理解和调试。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class SymmetricDifferenceExample {public static void main(String[] args) {List<Integer> list1 = new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);list1.add(4);List<Integer> list2 = new ArrayList<>();list2.add(2);list2.add(3);list2.add(4);// 存储结果Set<Integer> difference = new HashSet<>();// 遍历 list1,添加独有元素for (Integer item : list1) {if (!list2.contains(item)) {difference.add(item);}}// 遍历 list2,添加独有元素for (Integer item : list2) {if (!list1.contains(item)) {difference.add(item);}}System.out.println("对称差: " + difference); // 输出: 对称差: [1]}
}

方法 5:使用 Apache Commons Collections 的 CollectionUtils.disjunction

Apache Commons Collections 提供了 CollectionUtils.disjunction 方法,可以直接计算两个集合的对称差。

Maven 依赖

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version>
</dependency>

代码示例

import org.apache.commons.collections4.CollectionUtils;
import java.util.Arrays;
import java.util.List;public class SymmetricDifferenceExample {public static void main(String[] args) {List<Integer> list1 = Arrays.asList(1, 2, 3, 4);List<Integer> list2 = Arrays.asList(2, 3, 4);// 使用 CollectionUtils 计算对称差List<Integer> difference = (List<Integer>) CollectionUtils.disjunction(list1, list2);System.out.println("对称差: " + difference); // 输出: 对称差: [1]}
}

性能分析与总结

方法优点缺点
removeAll 两次简单直观,易于理解操作两个集合需要额外空间
Java 8 Stream灵活,代码优雅,适合复杂需求需要 Java 8 支持
Guava Sets.symmetricDifference代码简洁,性能高需要引入 Guava 库
手动遍历控制力强,适合无第三方库的项目代码繁琐,不适合大数据集
Apache CollectionUtils直接调用现成方法需要引入 Commons 库

推荐使用 Guava 或 Java 8 的流式操作。如果项目中已有这些依赖,这两种方式更高效、优雅。对于不支持 Java 8 的老项目,可以选择手动遍历或者 removeAll

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词