【问题标题】:Remove duplicate from a java collection从 java 集合中删除重复项
【发布时间】:2019-02-17 04:04:58
【问题描述】:
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。 IE。我预计 Employee 类型的另一个列表中有 54,123,332 个。

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

【问题讨论】:

  • 首先,你需要自己尝试;当您遇到特定问题时,欢迎您提出相关问题。
  • 我的小提示:试试看Set
  • 你需要在类中实现你的自定义比较器/相等。然后你可以把你的列表放在一个集合中。搜索有关如何实现比较器的教程。

标签: java arrays


【解决方案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());
        }
    }

}

【讨论】:

  • 大家好,感谢您的回复。我做了同样的事情,我创建了一个比较器并添加了我自己的排序逻辑来对 ID 进行排序。但我想通过组合排序来确保我想删除(ID + Name)
【解决方案2】:

如果您相应地覆盖 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&lt;Employee&gt; 的实现。类似于@bsb 提供的解决方案,但使用了java 8 特性。

【讨论】:

  • 我可以使用 ID。但我也想根据名称进行排序。就像在我的示例中一样,我有 54 个有 3 个名称。但在名称中我想获得名称 DESC。现在我面临如何获取该 ID 、 NAME 组合排序并获得正确的问题。
  • 您可以在此处查找具有多个字段的排序:stackoverflow.com/questions/4258700/…
【解决方案3】:

首先,这段代码不会编译,因为您没有实现类似的接口。因此,假设您为简洁起见,我暂时将其删除了:)。

假设你有这个......最明智的做法是首先使用地图。

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

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=Employee{id=54, name='cKongarass', 薪水='3000$', recordStatus='null', key=3}, 123=Employee{id=123, name='zMadhu', 工资='1000$',recordStatus='null',key=1},332=Employee{id=332, name='bSudhan',salary='2000$',recordStatus='null',key=2}}

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

Person 类 toString() 函数:

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

【讨论】:

    【解决方案4】:

    首先覆盖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&lt;Employee&gt;,它不会接受像这样的重复对象:

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

    看一个简单的Ideone demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 2015-02-20
      • 1970-01-01
      相关资源
      最近更新 更多