从ArrayList中删除重复元素

时间:2017-06-29 16:33:51

标签: java arraylist

我们有一个ArrayList。它包含重复的员工对象,只有年龄不同,但名称和ID将相同。因此,在删除重复项时,我们必须让员工保持最大年龄并删除所有其他重复项。这是一位采访者在其中一次采访中提出的问题之一。

我试着解决这个问题。它给了我正确的结果,但我不确定我的方法,因为我在equals方法中更改对象的状态。有没有其他方法可以解决这个问题? 下面的代码片段: -

package practice;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

class Employee {
    private int id;
    private String name;
    private int age;

    Employee(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int hashCode() {
        return (31*(name.hashCode()) + 31);

    }

    @Override
    public boolean equals(Object obj) {        
        if ((obj instanceof Employee)) {
            if (((Employee)obj).getId() == this.id && (((Employee)obj).getName().equalsIgnoreCase(this.name))) {
                if(this.age > ((Employee)obj).getAge()) {
                    ((Employee)obj).setAge(this.age);
                }
                return true;
            } else 
                return false;
        } else 
            return false;
    }
}

public class ListDuplicateRemoval {

    public static List<Employee> removeDuplicates(List<Employee> employees) {
        Set<Employee> set = new HashSet<>();
        for (int i = 0; i < employees.size(); i++) {
            set.add(employees.get(i));
        }        
        /*for (int i = 0; i < set.size(); i++) {
            System.out.println(set.iterator().next().getAge());
        }*/
        employees.removeAll(employees);
        employees.addAll(set);
        return employees;
    }

    public static void main(String[] args) {
        Employee e1 = new Employee(1, "Mike", 20);
        Employee e2 = new Employee(1, "Mike", 21);
        List <Employee> list = new ArrayList<>();
        list.add(e1);
        list.add(e2);
        removeDuplicates(list);
        System.out.println(list.size());
        System.out.println(list.get(0).getAge());
    }
}

2 个答案:

答案 0 :(得分:1)

这个解决方案真的很糟糕。 equals永远不应该修改它所比较的​​对象的状态。

创建一个包含唯一标识员工的信息的类,以及正确覆盖equal()和hashCode()的信息。然后使用包含这些身份验证信息的Map作为密钥,并使用年龄最大的员工作为值。然后获取值并将其设为列表:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

class Employee {
    private int id;
    private String name;
    private int age;

    Employee(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    int getId() {
        return id;
    }

    String getName() {
        return name;
    }

    int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Employee{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", age=" + age +
            '}';
    }
}

class DuplicateRemoval {

    public static void main(String[] args) {
        List<Employee> employeeList = Arrays.asList(
            new Employee(1, "Joe", 23),
            new Employee(2, "Joe", 23),
            new Employee(1, "Joe", 21),
            new Employee(1, "Jane", 22),
            new Employee(1, "Jane", 20)
        );

        Map<EmployeeKey, Employee> map = employeeList.stream().collect(
            Collectors.toMap(e -> new EmployeeKey(e.getId(), e.getName()),
                             Function.identity(),
                             (e1, e2) -> e1.getAge() > e2.getAge() ? e1 : e2)
        );

        List<Employee> result = new ArrayList<>(map.values());
        System.out.println("result = " + result);
    }

    private static class EmployeeKey {
        private int id;
        private String name;

        EmployeeKey(int id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            EmployeeKey that = (EmployeeKey) o;
            return id == that.id &&
                Objects.equals(name, that.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, name);
        }
    }
}

答案 1 :(得分:0)

实施Comparator<Employee>

  1. compare方法考虑到年龄。
  2. equals方法忽略年龄。
  3. 使用equals来识别重复项。

    使用compare确定要保留的副本。