我如何有效地比较 Java 中的两个大型对象列表,并识别一个列表中存在但另一个列表中不存在的项目?
例子:
假设我有两个包含数千名员工数据的大型 CSV 文件,其中包含姓名、部门和薪水列。需要比较两个文件并根据姓名和部门识别一个文件中存在但另一个文件中不存在的任何员工。
public static void compareCSVFiles(String file1, String file2) {
List<Employee> list1 = readCSVFile(file1);
List<Employee> list2 = readCSVFile(file2);
List<Employee> uniqueTo1 = new ArrayList<>();
List<Employee> uniqueTo2 = new ArrayList<>();
for (Employee emp1 : list1) {
boolean found = false;
for (Employee emp2 : list2) {
if (emp1.getName().equals(emp2.getName()) && emp1.getDepartment().equals(emp2.getDepartment())) {
found = true;
break;
}
}
if (!found) {
uniqueTo1.add(emp1);
}
}
for (Employee emp2 : list2) {
boolean found = false;
for (Employee emp1 : list1) {
if (emp2.getName().equals(emp1.getName()) && emp2.getDepartment().equals(emp1.getDepartment())) {
found = true;
break;
}
}
if (!found) {
uniqueTo2.add(emp2);
}
}
System.out.println("Employees unique to " + file1 + ":");
for (Employee emp : uniqueTo1) {
System.out.println(emp.getName() + " (" + emp.getDepartment() + ")");
}
System.out.println("Employees unique to " + file2 + ":");
for (Employee emp : uniqueTo2) {
System.out.println(emp.getName() + " (" + emp.getDepartment() + ")");
}
}
认为我们可以更有效地编写这些代码。想知道你对此的想法。 谢谢!
不使用列表,而是使用具有唯一标识符的地图(例如员工 ID) 然后运行第二个列表/地图以查看第一个地图是否包含它。
仅此一项就可以为您节省大量的复杂性/时间
您可以将它们加载到集合中(根据相等标准实现哈希码/等于)并相交/差异。如果内容适合内存,这将起作用。
如果您想要一个可扩展的解决方案,您可以在磁盘合并排序上对它们进行排序并逐行扫描。
最后,如果您想要一个真正可扩展的解决方案,那么请使用 Spark。
如果列表相等,则为 O(n) 操作。您可以使用:
Assert.assertEquals(list1, list2);
这依赖于 List::equals 来比较列表。
如果列表不相等,您将得到一个显示差异的异常。
因此,如果你想比较列表中的对象,你可以使用:
例如:
Arraylist a = {obj1, obj2, obj3};
Arraylist b={obj1, obj5, obj6};
List<Object> c = new ArrayList<Object>(a);
c.removeAll(b);
同样,考虑使用集合而不是列表。