7

この質問には、Java 8 コレクターを使用した要素のマッピングとグループ化が含まれます。私は患者のリストを持っています。各患者には、訪問した部門のリストがあります。Java 8 の新しいコレクター API を使用して各部門が訪問された回数をカウントしたい場合、部門リストでグループ化するにはどうすればよいでしょうか?

ありがとう!

注:各部門にカウンターを配置できることはわかっています。この質問は、Java 8 の新しい機能を学習することのみを目的としています。

コード:

public class Patient {
    private String id;
    private List<Department> history;
    /* some more getters/setters come here */
}

私の主な方法では、患者のリストを持っています。Department クラスを編集 (または拡張または装飾) せずに、Department ごとに訪問された回数を知りたいです。

患者の流れを取り、それらを部門->カウント(各患者がどの部門を何回訪れたか)のマップにマッピングする必要があると思います。これらのマップのストリームを持つ - これらのマップをグループ化してカウントするために何をすべきかわかりません。

4

1 に答える 1

11

まず、患者が部門を複数回訪問した場合、その部門は患者の履歴リストに複数回表示されると仮定します。

その場合は、患者のストリームとflatMapそれを部門のストリームに簡単に取得できます。部門の出現は、患者からの 1 回の訪問を示します。

groupingBy次に、これをコレクターに渡すことができます。部門自体で分類したいので、分類子関数は恒等関数です。

値については、Department のエントリがまだ存在しない場合は値として 1 を入力しますが、エントリが存在する場合は既存の値に 1 を追加します。すでにこれを行うという名前のコレクタがcounting()あるので、これを下流のコレクタとして に渡すだけgroupingBy()です。

結果のコードは次のとおりです。

import static java.util.stream.Collectors.*;

List<Patient> patients = ... ;

Map<Department, Long> frequency =
    patients.stream()
        .flatMap(p -> p.getHistory().stream())
        .collect(groupingBy(d -> d, counting()));

部門が訪問されていない場合は、単にマップに表示されないことに注意してください。部門のリストがある場合は、次のようにゼロの値を入力できます。

departments.forEach(d -> frequency.putIfAbsent(d, 0L));

getまたは、横のゼロを埋めたい場合は、

long numVisits = frequency.getOrDefault(dept, 0L);
于 2014-04-26T01:23:04.413 に答える