简体   繁体   中英

Get duplicated items with specific format from Java Stream

I'm new with Java streams and I'm playing around with them right now. 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"

So this is my person class, I have already override the equals method in order to get the duplicated based on my criterias

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
  • 4 Maureen Perez 15/07/92
  • 7 Andres Gonzalez 12/4/1990
  • 9 Maureen Perez 15/07/92
  • 11 Maureen Perez 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.

First of all, you should fix your hashCode() implementation to match your equals . If two objects are equal, they must have the same hashCode() .

Now, your Stream pipeline returns all elements, since your filter 's Predicate will always return true .

Instead, you can group equal elements of the 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. You can iterate this Map and print the Person s having List s with size > 1.

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()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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