从Java 8流中获取频率最高的对象

0yg35tkg  于 2023-01-16  发布在  Java
关注(0)|答案(2)|浏览(125)

我有一个包含cityzip字段的对象,我们称之为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));

现在,我有了一个Map,其中键是zip,值是包含该zipRecord对象的列表。
现在我想得到的是每个zip最常用的city

recordsByZip.forEach((zip, records) -> {
    final String mostCommonCity = //get most common city for these records
});

我希望对所有流操作都这样做。例如,我可以通过以下操作获得每个city的频率Map:

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
有没有Java8流Maven可以在这方面施展一些魔法?
如果您想尝试一下,这里有一个ideone sandbox

vbopmzt1

vbopmzt11#

您可以具有以下内容:

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()
            )
         ));

这将按邮编和城市对每条记录进行分组,计算每个邮编的城市数。然后,对按邮编划分的城市数Map进行后处理,以仅保留计数最大的城市。

ig9co6j1

ig9co6j12#

我认为Multiset是解决这类问题的一个很好的选择。

Stream.of(records).map(e -> e.getCity()).filter(N::notNullOrEmpty)
      .toMultiset().maxOccurrences().get().getKey();

披露:我是abacus-common的开发者。

相关问题