简体   繁体   English

从 Java Stream 获取具有特定格式的重复项

[英]Get duplicated items with specific format from Java Stream

I'm new with Java streams and I'm playing around with them right now.我是 Java 流的新手,我现在正在玩它们。 Given that I receive a list of persons I want to detect which of them are duplicated and print them as "{Id1} is duplicated with {Id3}{Id4} and its duplicated values are Name, Lastname, FamilyName and Birthday"鉴于我收到一个人名单,我想检测哪些人是重复的,并将它们打印为“{Id1} 与 {Id3}{Id4} 重复,其重复值是姓名、姓氏、家庭姓名和生日”

So this is my person class, I have already override the equals method in order to get the duplicated based on my criterias所以这是我的个人类,我已经覆盖了 equals 方法,以便根据我的标准获取重复项

public class Person {

private int id;
private String name;
private String familyName;
private String birthday;
private String city;

public Person(int id, String name, String familyName, String birthday, String city) {
    this.id = id;
    this.name = name;
    this.familyName = familyName;
    this.birthday = birthday;
    this.city = 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 getFamilyName() {
    return familyName;
}

public void setFamilyName(String familyName) {
    this.familyName = familyName;
}

public String getBirthday() {
    return birthday;
}

public void setBirthday(String birthday) {
    this.birthday = birthday;
}

public String getCity() {
    return city;
}

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

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

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return false;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final Person other = (Person) obj;
    if (!Objects.equals(name, other.name)) {
        return false;
    }
    if (!Objects.equals(familyName, other.familyName)) {
        return false;
    }

    if (!Objects.equals(birthday, other.birthday)) {
        return false;
    }
   return true;
}

} }

Then, I'm getting the list of duplicates in the following method然后,我在以下方法中获取重复项列表

personList.stream()
            .filter(p -> personList.contains(p))
            .collect(Collectors.toList()).forEach(p-> {
                System.out.println(p.getId() + " " + p.getName() + " " + p.getFamilyName() + " " + p.getBirthday());
            });

It prints the following:它打印以下内容:

  • 2 Andres Gonzalez 12/4/1990 2 安德烈斯·冈萨雷斯 12/4/1990
  • 4 Maureen Perez 15/07/92 4 莫琳佩雷斯 15/07/92
  • 7 Andres Gonzalez 12/4/1990 7 安德烈斯·冈萨雷斯 12/4/1990
  • 9 Maureen Perez 15/07/92 9 莫林佩雷斯 15/07/92
  • 11 Maureen Perez 15/07/92 11 莫琳佩雷斯 15/07/92

As you can see ID's 2 and 7 are duplicated and also 4,9 and 11 are duplicated and those ones are the ones that I need to print in that format but I don't know how to do it with streams so far.如您所见,ID 的 2 和 7 是重复的,并且 4,9 和 11 也是重复的,这些是我需要以该格式打印的那些,但到目前为止我不知道如何使用流进行打印。

First of all, you should fix your hashCode() implementation to match your equals .首先,您应该修复您的hashCode()实现以匹配您的equals If two objects are equal, they must have the same hashCode() .如果两个对象相等,则它们必须具有相同的hashCode()

Now, your Stream pipeline returns all elements, since your filter 's Predicate will always return true .现在,您的Stream管道返回所有元素,因为您的filterPredicate将始终返回true

Instead, you can group equal elements of the List :相反,您可以将List相等元素分组:

Map<Person,List<Integer>> grouped =
    personList.stream()
              .collect(Collectors.groupingBy(Function.identity(),
                                             Collectors.mapping(Person::getId,
                                                                Collectors.toList())));

Now, for each Person , you have an associated List of identifiers.现在,对于每个Person ,您都有一个关联的标识符List You can iterate this Map and print the Person s having List s with size > 1.您可以迭代此Map并打印具有大小 > 1 的ListPerson

For example:例如:

personList.stream()
          .collect(Collectors.groupingBy(Function.identity(),
                                         Collectors.mapping(Person::getId,
                                                            Collectors.toList())));
          .entrySet()
          .stream()
          .filter(e -> e.getValue().size() > 1)
          .forEach(e -> System.out.println(e.getKey().getId() + " " + e.getKey().getName() + " " + e.getKey().getFamilyName() + " " + e.getKey().getBirthday() + " " + e.getValue()));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM