如何根据属性查找两个数组列表之间的差异?
我有两个数组列表。 每个都有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建议。 您应该使用映射来获得比列表更有效的查找。 (删除涉及查找。)我建议设置,但是你需要实现equals
和hashcode
。 它们已经为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
。