如何根据属性查找两个数组列表之间的差异?

我有两个数组列表。 每个都有Employee类型的对象列表。

Employee类如下所示

public class Employee { Employee(String firstname, String lastname, String employeeId) { this.firstname = firstname; this.lastname = lastname; this.employeeId = employeeId; } private int id; // this is the primary key from employee table private String firstname; private String lastname; private String employeeId; // manually assigned unique id to each employee // getters and setters } 

我需要根据员工对象的属性(员工ID)找到两个列表之间的差异。

员工ID是为每个员工手动生成的唯一ID。

  import java.util.ArrayList; import java.util.List; public class FindDifferences { public static void main(String args[]){ List list1 = new ArrayList(); List list2 = new ArrayList(); list1.add(new Employee("F1", "L1", "EMP01")); list1.add(new Employee("F2", "L2", "EMP02")); list1.add(new Employee("F3", "L3", "EMP03")); list1.add(new Employee("F4", "L4", "EMP04")); list1.add(new Employee("F5", "L5", "EMP05")); list2.add(new Employee("F1", "L1", "EMP01")); list2.add(new Employee("F2", "L2", "EMP02")); list2.add(new Employee("F6", "L6", "EMP06")); list2.add(new Employee("F7", "L7", "EMP07")); list2.add(new Employee("F8", "L8", "EMP08")); List notPresentInList1 = new ArrayList(); // this list should contain EMP06, EMP07 and EMP08 List notPresentInList2= new ArrayList(); // this list should contain EMP03, EMP04 and EMP05 } } 

覆盖Employee类的equals()hashcode()方法,在检查相等性时仅使用employeeId (我不确定为什么需要id字段。你也可以将它包含在内)。 NetBeans / Eclipse IDE可以为您完成此任务。 然后,您可以创建原始列表的副本 ,并使用List.removeAll()来计算差异。

你的清单不是真正的清单,是吗? 他们实际上是没有明确订单的员工。 如果他们有明确的订单,他们将更容易比较。 为employeeId定义Comparator并使用Collections.sort对两个数组进行排序。 然后,您需要应用差异算法。 我没有看到任何好的通用的。 您可以将排序列表转换为XML,然后使用XMLUnit的Diff类来获取差异。 您可以将其渲染为字符串列表并应用文本差异 。 如果要实现特定于您的用例的差异算法,请参阅下面的讨论 。

在列表上使用removeAll方法:

 list1.removeAll(list2); 

此方法将删除list1和list2中的所有公共元素,因此在调用此方法后,list1包含以下员工ID,因为这些是list2中唯一的EMP03 EMP04 EMP05

并覆盖Employee Class中的equals方法

  @Override public boolean equals(Object obj) { Employee employee = (Employee)obj; if ( this.employeeId.equalsIgnoreCase(employee.employeeId)){ return true; } return false; } 

将两个员工列表放入地图中。 关键是employeeId 。 值是employee对象。 然后使用removeAll作为@AndrewButenko建议。 您应该使用映射来获得比列表更有效的查找。 (删除涉及查找。)我建议设置,但是你需要实现equalshashcode 。 它们已经为String实现了。

 Map map1 = new HashMap(); for (Employee e : list1) { map1.put(e.getEmployeeId(), e); } Map map2 = new HashMap(); for (Employee e : list2) { map2.put(e.getEmployeeId(), e); } // clone makes sure we don't mess with the original map2 because we will reuse it Collection notPresentInList1 = map2.clone().removeAll(map1).values(); Collection notPresentInList2 = map1.removeAll(map2).values(); 

如果您关心结果的顺序,可以在最后对集合进行排序,也可以使用TreeMap