Java 8 | 查找值最大的Map Entry

3

我有一个模型Person[city, name]。我将它们收集在Map中,并按城市分组。我需要追踪那个有最多人居住的城市,并将该条目作为Map的一部分返回。我已经尝试过了,而且它也能够工作,但是我想知道是否有更好的方法。

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中编写代码。

2
如果你的lambda表达式超过2-3行,那么它需要进行重构。——有远见的程序员 - Vishwa Ratna
mapOfMostPopulatedCity 总是只有一个元素。为什么要使用 HashMap? - Twister
@Twister 还有什么可以代替这个?需要表示键和值。 - sandeep pandey
Map.Entry<String, List<Person>> result = persons.stream() .collect(Collectors.groupingBy(Person::getCity)).entrySet().stream() .max(Comparator.comparingInt(e -> e.getValue().size())) .orElseThrow(IllegalArgumentException::new); - Twister
2个回答

5
假设你有一个人员列表。
List<Person> persons = new ArrayList<Person>();

首先根据城市对它们进行分组,然后获取列表中值最大的条目。max将返回EntryOptional,所以我不会让它变得复杂,我只会使用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

5
在获取到最大的Map条目后,您需要将其转换为仅有一个条目的Map。为此,您可以使用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())来使用单个条目构建地图。


2
在Java 9中,您还可以使用.map(Map :: ofEntries),因为输入已经是Map.Entry - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接