java8 请获取两个list差值
在Java 8中获取两个List<String>的差值,主要有几种常见场景:
1. 获取 list1 中有而 list2 中没有的元素(差集)
java
import java.util.*;
import java.util.stream.Collectors;
public class ListDifference {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("A", "B", "C", "D", "E");
List<String> list2 = Arrays.asList("B", "D", "F", "G");
// 方法1:使用 Stream API(推荐)
List<String> difference1 = list1.stream()
.filter(item -> !list2.contains(item))
.collect(Collectors.toList());
System.out.println("list1 - list2: " + difference1);
// 输出: [A, C, E]
// 方法2:使用 HashSet(性能更好,适合大数据量)
Set<String> set2 = new HashSet<>(list2);
List<String> difference2 = list1.stream()
.filter(item -> !set2.contains(item))
.collect(Collectors.toList());
System.out.println("list1 - list2: " + difference2);
// 方法3:使用 removeAll
List<String> copy1 = new ArrayList<>(list1);
copy1.removeAll(list2);
System.out.println("list1 - list2: " + copy1);
}
}2. 获取两个列表的对称差集(两个列表互不包含的元素)
java
public class SymmetricDifference {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("A", "B", "C", "D", "E");
List<String> list2 = Arrays.asList("B", "D", "F", "G");
// 方法1:合并两个差集
Set<String> set1 = new HashSet<>(list1);
Set<String> set2 = new HashSet<>(list2);
List<String> symmetricDiff = new ArrayList<>();
// 添加 list1 有 list2 没有的
symmetricDiff.addAll(list1.stream()
.filter(item -> !set2.contains(item))
.collect(Collectors.toList()));
// 添加 list2 有 list1 没有的
symmetricDiff.addAll(list2.stream()
.filter(item -> !set1.contains(item))
.collect(Collectors.toList()));
System.out.println("对称差集: " + symmetricDiff);
// 输出: [A, C, E, F, G]
// 方法2:使用 HashSet 的对称差操作
Set<String> difference = new HashSet<>(list1);
difference.addAll(list2); // 并集
Set<String> intersection = new HashSet<>(list1);
intersection.retainAll(list2); // 交集
difference.removeAll(intersection); // 并集 - 交集 = 对称差集
System.out.println("对称差集: " + new ArrayList<>(difference));
}
}3. 考虑重复元素的差值
java
public class DifferenceWithDuplicates {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("A", "A", "B", "C", "C", "D");
List<String> list2 = Arrays.asList("A", "B", "B", "D");
// 创建可修改的副本
List<String> list1Copy = new ArrayList<>(list1);
List<String> list2Copy = new ArrayList<>(list2);
// 移除交集元素
for (String item : list2) {
list1Copy.remove(item);
}
System.out.println("考虑重复的差集 (list1 - list2): " + list1Copy);
// 输出: [A, C, C]
// 使用 Map 统计计数
Map<String, Long> count1 = list1.stream()
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
Map<String, Long> count2 = list2.stream()
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
List<String> result = new ArrayList<>();
for (Map.Entry<String, Long> entry : count1.entrySet()) {
String key = entry.getKey();
Long countIn2 = count2.getOrDefault(key, 0L);
long diff = entry.getValue() - countIn2;
if (diff > 0) {
for (int i = 0; i < diff; i++) {
result.add(key);
}
}
}
System.out.println("考虑重复的差集 (list1 - list2): " + result);
// 输出: [A, C, C]
}
}4. 使用 Guava 库(更简洁)
java
import com.google.common.collect.Sets;
import com.google.common.collect.Lists;
public class GuavaDifference {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("A", "B", "C", "D", "E");
List<String> list2 = Arrays.asList("B", "D", "F", "G");
// 差集
Sets.SetView<String> difference = Sets.difference(
new HashSet<>(list1),
new HashSet<>(list2)
);
System.out.println("list1 - list2: " + difference);
// 对称差集
Sets.SetView<String> symmetricDiff = Sets.symmetricDifference(
new HashSet<>(list1),
new HashSet<>(list2)
);
System.out.println("对称差集: " + symmetricDiff);
}
}性能建议:
- 对于小数据集:使用
stream().filter()即可 - 对于大数据集:先将
list2转换为HashSet以提高contains()的性能 - 需要考虑顺序:使用
LinkedHashSet或ArrayList - 考虑重复元素:需要使用计数方法
根据你的具体需求选择合适的实现方式。