sandeep pandey :
I have model Person[city, name]. I have collected them in Map And Grouped them by city. I need to trace the city that has most no of person staying there and return only that entry as part of Map. I'v tried and also it is working but i was wondering is there any better way of doing.
Comparator<Entry<String, List<Person>>> compareByCityPopulation =
Comparator.comparing(Entry<String, List<Person>>::getValue, (s1, s2) -> {
return s1.size() - s2.size();
});
HashMap mapOfMostPopulatedCity = persons.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Person::getCity), m -> {
Entry<String, List<Person>> found = m.entrySet().stream().max(compareByCityPopulation).get();
HashMap<String, List<Person>> hMap = new HashMap<>();
hMap.put(found.getKey(), found.getValue());
return hMap;
}));
System.out.println("*City with Most no of people*");
mapOfMostPopulatedCity.forEach((place, peopleDetail) -> System.out.println("Places " + place + "-people detail-" + peopleDetail));
Please Suggest how can we write better in java 8.
Ravindra Ranwala :
After getting the max map entry, you have to convert that into a map which has a single entry. For that you can use Collections.singletonMap()
Map<String, List<Person>> mapOfMostPopulatedCity = persons.stream()
.collect(Collectors.groupingBy(Person::getCity)).entrySet().stream()
.max(Comparator.comparingInt(e -> e.getValue().size()))
.map(e -> Collections.singletonMap(e.getKey(), e.getValue()))
.orElseThrow(IllegalArgumentException::new);
With Java9 you can use Map.of(e.getKey(), e.getValue())
to build the map with a single entry.