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

时间:2012-06-29 11:03:26

标签: java arraylist find

我有两个数组列表。每个都有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<Employee> list1 = new ArrayList<Employee>(); 
        List<Employee> list2 = new ArrayList<Employee>(); 

        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<Employee> notPresentInList1 = new ArrayList<Employee>(); 
        // this list should contain EMP06, EMP07 and EMP08

        List<Employee> notPresentInList2= new ArrayList<Employee>(); 
        // this list should contain EMP03, EMP04 and EMP05



    }

}

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:0)

你的名单不是真正的名单,不是吗?他们实际上是没有明确订单的员工。如果他们有明确的订单,他们将更容易比较。为employeeId定义Comparator并使用Collections.sort对两个数组进行排序。然后,您需要应用差异算法。我没有看到任何好的通用的。您可以将已排序的列表转换为XML,然后使用XMLUnit's Diff class来获取差异。您可以将其呈现为字符串列表并应用textual diff。如果您想实现一个特定于您的用例的算法,那么这里有一个discussion差异算法。

答案 2 :(得分:0)

在列表中使用removeAll方法:

list1.removeAll(list2);

此方法将删除list1和list2中的所有公共元素,因此在调用此方法后,list1包含以下employee 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;

    }

答案 3 :(得分:0)

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

Map<String, Employee> map1 = new HashMap<String, Employee>();
for (Employee e : list1) {
    map1.put(e.getEmployeeId(), e);
}
Map<String, Employee> map2 = new HashMap<String, Employee>();
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<Employee> notPresentInList1 = map2.clone().removeAll(map1).values();

Collection<Employee> notPresentInList2 = map1.removeAll(map2).values();

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