我有个人模型Person [city,name]。我已将它们收集在“地图”中并按城市分组。我需要跟踪没有人居住的城市,并仅返回该条目作为地图的一部分。我试过了,而且它还在工作,但我想知道还有没有更好的方法。
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));
请建议我们如何在Java 8中更好地编写代码。
答案 0 :(得分:5)
假设您有人员列表
List<Person> persons = new ArrayList<Person>();
然后首先根据城市将它们分组,然后在列表max
中获得最大值的条目将返回Optional
中的Entry
,因此我不会使其复杂化只需使用HashMap
来存储结果(如果结果以可选形式出现),否则将返回空的Map
Map<String, List<Person>> resultMap = new HashMap<>();
persons.stream()
.collect(Collectors.groupingBy(Person::getCity)) //group by city gives Map<String,List<Person>>
.entrySet()
.stream()
.max(Comparator.comparingInt(value->value.getValue().size())) // return the Optional<Entry<String, List<Person>>>
.ifPresent(entry->resultMap.put(entry.getKey(),entry.getValue()));
//finally return resultMap
答案 1 :(得分:5)
获取最大地图条目后,您必须将其转换为具有单个条目的地图。为此,您可以使用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);
使用Java9,您可以使用Map.of(e.getKey(), e.getValue())
通过一个条目来构建地图。