从Java集合中删除重复项

时间:2018-09-12 13:31:53

标签: java arrays

public class Employee implements Comparable<Employee> {

    private int id;
    private String name;
    private String salary;
    private String recordStatus;
    private int key;

    public Employee(int id, String name, String salary, int key) {
        super();
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.key = key;
    }
}

现在我有一个Employee类型的列表。

List<Employee> list = new ArrayList<Employee>();
list.add(new Employee(123, "zMadhu", "1000$",1));
list.add(new Employee(332, "bSudhan", "2000$",2));
list.add(new Employee(54, "cKongarass", "3000$",3));
list.add(new Employee(54, "xKongarass", "3000$",4));
list.add(new Employee(54, "aKongarass", "3000$",5));

现在,我想从此列表中删除数据,并且只有唯一的IDS。即我期望在Employee类型的另一个列表中达到54,123,332。

想看看我该怎么做。非常感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

首先覆盖equals(..)hashCode(),而仅使用id

...

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Employee)) return false;

    Employee employee = (Employee) o;

    return id == employee.id;
}

@Override
public int hashCode() {
    return id;
}
...

第二个只需创建一个Set<Employee>,它将不接受重复的对象,就像这样:

Set<Employee> result = new HashSet<>(list);// [54, 123, 332]

看看一个简单的Ideone demo

答案 1 :(得分:2)

首先,由于您没有实现类似的接口,因此无法编译此代码。所以,假设您为简洁起见,我暂时将其删除:)。

假设您有...最明智的方法就是首先使用地图。

假设您想从此列表开始,您可以将其转换为地图,并使用流记录/删除重复项

Map<Integer, Employee> employees = list.stream()
        .collect(Collectors.toMap(k -> k.id, v -> v, (a, b) -> {
    System.out.println("Duplicate found! " + a.id + " taking first one.");
    return a;
}));
System.out.println(employees);

结果:

  

发现重复! 54 获得第一个。

     

发现重复! 54 获得第一个。

     

{54 =雇员{id = 54,名称='cKongarass',工资='3000 $',   recordStatus ='null',key = 3},123 = Employee {id = 123,name ='zMadhu',   工资='1000 $',recordStatus ='null',键= 1},332 =员工{id = 332,   名称='bSudhan',薪水='2000 $',recordStatus ='null',键= 2}}

为员工正确打印请注意,您需要在类中添加toString()方法。

人员类toString()函数:

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

答案 2 :(得分:1)

删除重复项的最简单方法是将List传递给Set,然后使用Comparator删除重复项。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class RemoveDuplicate {

    public static void main(String[] args) {

        List<Employee> list = new ArrayList<Employee>();
        list.add(new Employee(123, "zMadhu", "1000$",1));
        list.add(new Employee(332, "bSudhan", "2000$",2));
        list.add(new Employee(54, "cKongarass", "3000$",3));
        list.add(new Employee(54, "xKongarass", "3000$",4));
        list.add(new Employee(54, "aKongarass", "3000$",5));

        //Printing original list
        for (Employee emp : list) {
            System.out.println(emp.getId());
        }

        Set<Employee> set = new TreeSet<Employee>(new Comparator<Employee>() {

            @Override
            public int compare(Employee e1, Employee e2) {
                return e1.getId() == e2.getId() ? 0 : 1;
            }
        });
        set.addAll(list);

        final ArrayList<Employee> newList = new ArrayList<Employee>(set);

        System.out.println("\n***** After removing duplicates *******\n");
        for (Employee emp : newList) {
            System.out.println(emp.getId());
        }
    }

}

答案 3 :(得分:1)

如果您相应地覆盖equals方法,则可以在Java 8+中以这种方式进行操作:

import java.util.stream.Collectors;

list.stream().distinct().collect(Collectors.toList())

在不覆盖equals方法的情况下也可以实现,但是更冗长:

Set<Employee> uniqueSet = new TreeSet<>((e1, e2) -> e1.getId() == e2.getId() ? 0 : 1);
set.addAll(list);

List<Employee> result = new ArrayList<>(uniqueSet);

传递给TreeSet构造函数的lambda扩展为Comparator<Employee>的实现。与@bsb提供的解决方案相似,但使用的是Java 8功能。