Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Java 8 – Stream API – groupingby not working

I want to use the Stream API to group a list of persons by name and city.
I have following code (in Java 8):

    class Person {
        private String name;
        private String gender;
        private String city;
        
        Person(String name, String gender, String city) {
            this.name   = name;
            this.gender = gender;
            this.city   = city;
        }
    }
    
    class PGroup {
        final String name;
        final String city;
        
        public PGroup(String name, String city) {
            this.name = name;
            this.city = city;
        }       
    }
    
    List<Person> people = new ArrayList<>();
    people.add(new Person("Thomas", "M", "Cologne"));
    people.add(new Person("Wilma",  "F", "Cologne"));
    people.add(new Person("Lydia",  "F", "Munich"));
    people.add(new Person("Thomas", "M", "Cologne"));
    
    Map<PGroup, List<Person>> map = people.stream()
            .collect(Collectors.groupingBy(t -> new PGroup(t.name, t.city)));
    
    for (PGroup p : map.keySet()) {
        System.out.println("name: " + p.name + ", city: " + p.city);
    }

If I run this code I get:

name: Wilma, city: Cologne
name: Thomas, city: Cologne
name: Lydia, city: Munich
name: Thomas, city: Cologne

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

As we can see the List was not grouped at all.
I expect only 3 entries, since Thomas in Cologne exists twice and we want to group by name and city:

name: Wilma, city: Cologne
name: Thomas, city: Cologne
name: Lydia, city: Munich

Why it is not grouped? What I am missing please?

>Solution :

Try to override the equals and hashcode functions of PGroup class.
Try to replace the class code with below:

class PGroup {
    final String name;
    final String city;

    public PGroup(String name, String city) {
        this.name = name;
        this.city = city;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof PGroup)) return false;
        PGroup pGroup = (PGroup) o;
        return Objects.equals(name, pGroup.name) && Objects.equals(city, pGroup.city);
    }

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

Reason:
The default implementation of the .equals() method compares the object references or the memory location where the objects are stored in the heap. Thus by default the .equals() method checks the object by using the “==” operator. Read more on equals and hashcode functions here

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading