我有一个包含city
和zip
字段的对象,我们称之为Record
。
public class Record() {
private String zip;
private String city;
//getters and setters
}
现在,我有一些这些对象的集合,我使用以下代码按zip
对它们进行分组:
final Collection<Record> records; //populated collection of records
final Map<String, List<Record>> recordsByZip = records.stream()
.collect(Collectors.groupingBy(Record::getZip));
所以,现在我有一张地图,其中键是zip
,而值是Record
个zip
对象的列表。
我现在想要获得的是每个city
最常见的zip
。
recordsByZip.forEach((zip, records) -> {
final String mostCommonCity = //get most common city for these records
});
我想对所有流操作执行此操作。例如,我可以通过执行以下操作获取每个city
的频率图:
recordsByZip.forEach((zip, entries) -> {
final Map<String, Long> frequencyMap = entries.stream()
.map(GisSectorFileRecord::getCity)
.filter(StringUtils::isNotBlank)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
});
但我希望能够进行单行流操作,只返回最频繁的city
。
是否有任何Java 8流专家可以在这方面发挥作用?
如果你想玩它,可以使用ideone sandbox。
答案 0 :(得分:8)
您可以拥有以下内容:
final Map<String, String> mostFrequentCities =
records.stream()
.collect(Collectors.groupingBy(
Record::getZip,
Collectors.collectingAndThen(
Collectors.groupingBy(Record::getCity, Collectors.counting()),
map -> map.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey()
)
));
按照邮政编码和各城市对每个记录进行分组,计算每个邮政编码的城市数量。然后,通过zip对城市数量的地图进行后处理,以仅保留具有最大数量的城市。
答案 1 :(得分:1)
我认为Multiset是这类问题的不错选择。这是AbacusUtil
的代码Stream.of(records).map(e -> e.getCity()).filter(N::notNullOrEmpty).toMultiset().maxOccurrences().get().getKey();
披露:我是AbacusUtil的开发者。