如何在Java中实现类似SQL EXCEPT/MINUS的数据集重复记录排除?
Java实现类似SQL EXCEPT/MINUS的去重操作
针对你要从数据集2中排除与数据集1重复记录的需求,Java里有多种等价实现方式,下面结合你的数据集给出具体方案:
第一步:定义数据模型
首先需要创建一个Person类,并重写equals()和hashCode()方法,这样才能正确判断两条记录是否为重复(即Name和Age都一致):
import java.util.Objects; public class Person { private String name; private int age; // 构造方法 public Person(String name, int age) { this.name = name; this.age = age; } // Getter方法 public String getName() { return name; } public int getAge() { return age; } // 重写equals和hashCode,以Name+Age作为重复判断依据 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && name.equals(person.name); } @Override public int hashCode() { return Objects.hash(name, age); } // 重写toString方便打印结果 @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } }
方法一:使用Java 8+ Stream API(推荐)
利用Stream.filter()结合noneMatch(),逻辑和SQL的NOT EXISTS类似,筛选出数据集2中不存在于数据集1的记录:
import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { // 初始化数据集1 List<Person> dataset1 = List.of( new Person("John", 32), new Person("Vic", 29), new Person("Mary", 28), new Person("Rea", 29) ); // 初始化数据集2 List<Person> dataset2 = List.of( new Person("John", 32), new Person("Joe", 37), new Person("Mary", 28), new Person("Bo", 35) ); // 筛选出dataset2中不在dataset1的记录 List<Person> result = dataset2.stream() .filter(person -> dataset1.stream().noneMatch(p -> p.equals(person))) .collect(Collectors.toList()); // 打印结果:输出Joe和Bo的记录 result.forEach(System.out::println); } }
方法二:使用集合的removeAll()方法
如果数据集是可修改的集合(比如ArrayList),可以直接调用removeAll()方法,它会根据equals()的结果移除所有重复元素:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<Person> dataset1 = new ArrayList<>(List.of( new Person("John", 32), new Person("Vic", 29), new Person("Mary", 28), new Person("Rea", 29) )); List<Person> dataset2 = new ArrayList<>(List.of( new Person("John", 32), new Person("Joe", 37), new Person("Mary", 28), new Person("Bo", 35) )); // 移除dataset2中与dataset1重复的元素 dataset2.removeAll(dataset1); // 打印结果 dataset2.forEach(System.out::println); } }
方法三:传统循环遍历判断
如果不使用Stream或集合内置方法,也可以手动遍历数据集2,逐个判断是否存在于数据集1中:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<Person> dataset1 = List.of( new Person("John", 32), new Person("Vic", 29), new Person("Mary", 28), new Person("Rea", 29) ); List<Person> dataset2 = List.of( new Person("John", 32), new Person("Joe", 37), new Person("Mary", 28), new Person("Bo", 35) ); List<Person> result = new ArrayList<>(); for (Person p2 : dataset2) { boolean isDuplicate = false; for (Person p1 : dataset1) { if (p1.equals(p2)) { isDuplicate = true; break; } } if (!isDuplicate) { result.add(p2); } } // 打印结果 result.forEach(System.out::println); } }
优化提示
如果处理大数据量集合,为了提升查询效率,可以先把数据集1转成HashSet,利用其O(1)的查询速度优化判断逻辑:
import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Person> dataset1 = List.of( new Person("John", 32), new Person("Vic", 29), new Person("Mary", 28), new Person("Rea", 29) ); List<Person> dataset2 = List.of( new Person("John", 32), new Person("Joe", 37), new Person("Mary", 28), new Person("Bo", 35) ); Set<Person> dataset1Set = new HashSet<>(dataset1); List<Person> result = dataset2.stream() .filter(p -> !dataset1Set.contains(p)) .collect(Collectors.toList()); result.forEach(System.out::println); } }
内容的提问来源于stack exchange,提问作者miikey722
相关产品推荐
相关产品推荐

