当前位置: 首页 > 知识库问答 >
问题:

使用java 8[重复]查找重复项

汪鸿波
2023-03-14

我有一个带有ID,姓名和地址字段的员工类。如果两个雇员的 ID 和姓名完全相同,则认为他们是一样的。现在我有一个员工列表,现在我的任务是收集重复的员工。

这是我的员工类代码,带有基于id和name字段重写的hascode和equals方法。

class Employee {
    int id;
    String name;
    String address;

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

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", address=" + address + "]";
    }


    // auto generated by eclipse based on fields for id and name    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

现在我有这个代码可以找到重复的员工

public static void main(String[] args) {
    Employee e1 = new Employee(1, "John", "SFO");
    Employee e2 = new Employee(2, "Doe", "NY");
    Employee e3 = new Employee(1, "John", "NJ");

    List<Employee> list = Arrays.asList(e1, e2, e3);

    Set<Employee> set = new HashSet<>();
    for (int i = 0; i < list.size(); i++) {
        for (int j = i + 1; j < list.size(); j++) {
            if (list.get(i).equals(list.get(j))) {
                set.add(list.get(i));
            }
        }
    }

    System.out.println(set);
}

这段代码运行良好,并在我的集合中给出了id为1的雇员。

如何使用Java 8 lamda和streams执行相同的操作?在这种情况下,平面图是否有帮助?

共有2个答案

潘俊
2023-03-14

另一种方法:

list.stream()
    .collect(groupingBy(identity(), counting()))        
    .entrySet()
    .stream()
    .filter(e -> e.getValue() != 1)
    .map(Map.Entry::getKey)
    .collect(toList());

或者:

list.stream()
    .collect(groupingBy(identity()))        
    .values()
    .stream()
    .filter(l -> l.size() != 1)
    .map(l -> l.get(0))                 // The list cannot be empty
    .collect(toList());
梁丘兴腾
2023-03-14

你的要求有点具体,在大多数情况下没有真正的帮助。我会做类似的事情来代替:

final Map<Employee, Long> groupedWithCount = employees.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

现在你已经有了所有你需要的信息,甚至更多。在此图中,员工按人数分组,对于您的数据,情况如下:

{
  Employee [id=2, name=Doe, address=NY] = 1,
  Employee [id=1, name=John, address=SFO] = 2
}

显然,重复是有价值的条目

 类似资料:
  • 我试图列出整数列表中的重复元素,例如, 使用jdk 8的流。有人试过吗?要删除重复项,我们可以使用distinct() api。但是如何找到重复的元素呢?有人能帮我吗?

  • 我们有一个包含以下各栏的照片表: 此表包含组合的重复值。因此,一行可能会出现多次。 删除这些重复的最好方法是什么?(我用的是PostgreSQL 9.2和Rails 3。)

  • 1.3. 查找重复的行 对文件做拷贝、打印、搜索、排序、统计或类似事情的程序都有一个差不多的程序结构:一个处理输入的循环,在每个元素上执行计算处理,在处理的同时或最后产生输出。我们会展示一个名为dup的程序的三个版本;灵感来自于Unix的uniq命令,其寻找相邻的重复行。该程序使用的结构和包是个参考范例,可以方便地修改。 dup的第一个版本打印标准输入中多次出现的行,以重复次数开头。该程序将引入i

  • 我有一个对象,我想根据以下条件删除重复的对象:比较值,如果至少有一个具有的值为,则使用该对象并删除具有相同值的其余对象。 输入数据示例: 结果应该是:

  • 问题内容: 当LastDate中存在差异时,以下SQL可用于识别唯一的电话。但是,如果重复的电话具有完全相同的LastDate,则它将不起作用。 任何想法将不胜感激。 问题答案: 更改为。