Java8中从列表中删除重复项

8

我有一个如下所示的类,想要去除包含相同姓名的重复人员,如何使用Java8 Lambda进行操作,预期的List应该包含下面的p1、p3。

Person:

public class Person {

public int id;
public String name;
public String city;

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 String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

}

测试:

import java.util.ArrayList;
import java.util.List;

public class Testing {

public static void main(String[] args) {

    List<Person> persons = new ArrayList<>();

    Person p1 = new Person();
    p1.setId(1);
    p1.setName("Venkat");
    p1.setCity("Bangalore");
    Person p2 = new Person();

    p2.setId(2);
    p2.setName("Venkat");
    p2.setCity("Bangalore");

    Person p3 = new Person();
    p3.setId(3);
    p3.setName("Kumar");
    p3.setCity("Chennai");

    persons.add(p1);
    persons.add(p2);
    persons.add(p3);

}
}

1
请查看以下链接:https://dev59.com/tV0b5IYBdhLWcg3wC9aJ - Adrian
在Person类中重写equals和hashCode方法,使用Set进行去重。 - Noman Khan
请将以下与编程相关的内容从英文翻译成中文。只返回翻译后的文本:https://dev59.com/v2Ag5IYBdhLWcg3wWpxE[输入链接说明](https://dev59.com/v2Ag5IYBdhLWcg3wWpxE) - 取一个好的名字
3个回答

35

你可以过滤它们并生成一个独特的Set

Set<Person> set = persons.stream()
            .collect(Collectors.toCollection(() -> 
                 new TreeSet<>(Comparator.comparing(Person::getName))));

或者更好:

Set<String> namesAlreadySeen = new HashSet<>();

persons.removeIf(p -> !namesAlreadySeen.add(p.getName()));

哦,你比我快,+1!你应该告诉 OP 把 persons 改成 List<Person> 而不是 List<Object> - holi-java
4
你其实不需要流来做这个,是吧?只需使用比较器创建TreeSet,然后使用addAll即可。 - fps
1
这里不需要块语法,你可以像这里一样使用紧凑的表达式语法。 - Holger
1
@FedericoPeraltaSchaffner 你是对的,我不必使用流... 谢谢 - Eugene
帮我解决了另外一种问题 :p - Majid Ali Khan

33
List<Person> personsWithoutDuplicates = persons.stream()
 .distinct()
 .collect(Collectors.toList());

3
如果这个类重写了equals和hash方法,你确定这个方法还能正常工作吗? - Robert Moskal
5
问题实际上是为什么你想要悄悄地实现equalshashCode,而不是如何实现它们。 - Priidu Neemre
distinct - 返回一个流,其中包含此流的不同元素(根据Object.equals(Object))。 - Taras Melnyk

0
List<Person> modified = pesrons.stream().collect(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(Person::getName)))).stream().collect(Collectors.toList());

这将根据名称返回一个去重后的列表。
你也可以参考这个链接 在Java 8中基于属性从对象列表中移除重复项

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接