2016-09-16 7 views
6

私はcityzipというフィールドを持つオブジェクトを持っています。それをRecordとしましょう。Java 8ストリームから最大頻度のオブジェクトを取得する

public class Record() { 
    private String zip; 
    private String city; 

    //getters and setters 
} 

は今、私は次のコードを使用してzipすることにより、これらのオブジェクトのコレクション、およびIグループにそれらを持っている:

final Collection<Record> records; //populated collection of records 
final Map<String, List<Record>> recordsByZip = records.stream() 
    .collect(Collectors.groupingBy(Record::getZip)); 

そうに、今私は鍵がzipとされたマップを持っています値はzipRecordオブジェクトのリストです。

それぞれzipのうち、最も一般的なのはcityです。

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

これはすべてのストリーム操作で行いたいと思います。

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:たとえば、私はこれを行うことにより、各city用周波数のマップを取得することができています。

これにいくつかの魔法を働かせることができるJava 8ストリームガウスがありますか?

ここでは遊びたい場合はideone sandboxです。

答えて

6

次を持つことができます:

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

このグループの各レコードを自分の郵便番号によって、およびその都市で、各ジッパーのための都市の数を数えます。次に、ジップごとの都市数のマップを後処理して、最大カウントを有する都市のみを維持する。

+1

'collectingAndThen'私は何か不足していることを知っていましたが、私は常に代わりに'マッピング 'を考えています。 +1 –

+0

'.max()'によって返された 'Optional'が' .get() 'を呼び出す前にストリーム操作に存在するかどうかを調べる方法はありますか? –

+1

@AndrewMairoseはい、 '.get()'はここで呼び出すのが安全です。マップは空ではありません。少なくとも、少なくともzipでグループ化された都市が含まれている必要があります。 – Tunaki

0

私はMultisetがこの種の質問に適していると思います。ここでは、コードAbacusUtil

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

開示することです:私はAbacusUtilの開発者です。

関連する問題