-2

I have a list<Person> and what i want is to group the list elements by Person.age into a HashMap where the key is the Person.age and value is the count of elements in group.

Class Person { String name; int age; }

Then i am grouping them by using the below line:

Map<Integer,List<Person>> groupByAgeMap = personList.stream() .collect(Collectors.groupingBy(Person::getAge));

But what i exactly want is a Map where map key = Person.age and value = number of elements in the list for that age.

Right now i am achieving it with the below line:

Map<Integer,Integer> groupByAgeCountMap = new HashMap<>(); groupByAgeMap.forEach((k, v) -> groupByAgeCountMap.put(k, v.size()));

But it doesn't feel right as i am iterating the MAP. There must be some direct way using the streaming. Any help will be appreciated.

Giving the complete example::

package com.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    String name;
    int age;
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the age
     */
    public int getAge() {
        return age;
    }
    /**
     * @param age the age to set
     */
    public void setAge(int age) {
        this.age = age;
    }
}

public class GroupPerson {
    public Map<Integer,Integer> getTimesOfferOpened() {
        List<Person> personList = new ArrayList<>();

        Person person1 = new Person();
        person1.setName("Person1");
        person1.setAge(10);

        Person person2 = new Person();
        person2.setName("Person2");
        person2.setAge(10);

        Person person3 = new Person();
        person3.setName("Person3");
        person3.setAge(8);

        personList.add(person1);
        personList.add(person2);
        personList.add(person3);

        Map<Integer,List<Person>> personGroupdByAgeMap = personList.stream().collect(Collectors.groupingBy(Person::getAge));

        // Truncating all the data and returning the map only with count
        Map<Integer,Integer> numberOfPersonCountByAgeMap = new HashMap<>();
        personGroupdByAgeMap.forEach((k, v) -> numberOfPersonCountByAgeMap.put(k, v.size()));
        return numberOfPersonCountByAgeMap;
    }

    public static void main(String args) {
        GroupPerson obj = new GroupPerson();
        System.out.println(obj.getTimesOfferOpened());
    }
}
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • It would make it easier for us to help you if you'd provide a short but complete program demonstrating the problem - including sample data and expected output. Then we could test our potential solutions without *each* answerer having to write their own test app. – Jon Skeet Oct 30 '15 at 07:23
  • 3
    I suspect you just want `Collectors.groupingBy(Person::getAge, Collectors::counting)` though. – Jon Skeet Oct 30 '15 at 07:29
  • @JonSkeet: I have edited my question with the actual class. I am able to achieve the desired by using above code that gives me the Map as below {10=2, 8=1} What i want is to remove iterating `personGroupdByAgeMap` to get the `numberOfPersonCountByAgeMap`. I hope i am clear now. – Anshul Bhatnagar Oct 30 '15 at 07:57
  • I was able to achieve it with the below: `Map personGroupdByAgeMap = personList.stream() .collect(Collectors.groupingBy(Person::getCount, Collectors.counting())) ;` – Anshul Bhatnagar Oct 30 '15 at 08:18
  • Right - so I suggest you either add an answer yourself, or delete the question. – Jon Skeet Oct 30 '15 at 08:21

1 Answers1

0

I was able to achieve it with the below:

Map<Integer,Long> personGroupdByAgeMap = personList.stream() .collect(Collectors.groupingBy(Person::getCount, Collectors.counting())) ;