web-dev-qa-db-ja.com

ストリームを使用したJava 8のマップ値によるグループ化

Javaストリームを使用して、キーnomでグループ化するマップのリストがあります。

[
      {
        "dateDebut": "2018-07-01T00:00:00.000+0000",
        "nom": "Julien Mannone",
        "etat": "Impayé"
      },
      {
        "dateDebut": "2018-08-01T00:00:00.000+0000",
        "nom": "Julien Mannone",
        "etat": "Impayé"
      },          
      {
        "dateDebut": "2018-10-01T00:00:00.000+0000",
        "nom": "Mathiew Matic",
        "etat": "payé"
      },           
      {
        "dateDebut": "2018-10-01T00:00:00.000+0000",
        "nom": "Ash Moon",
        "etat": "payé"
      }
    ]

だから私は結果としてこのようなものが欲しい

{  
   "Julien Mannone":[  
      {  
         "dateDebut":"2018-07-01T00:00:00.000+0000",
         "etat":"Impayé"
      },
      {  
         "dateDebut":"2018-08-01T00:00:00.000+0000",
         "etat":"Impayé"
      }
   ],
   "Mathiew Matic":[  
      {  
         "dateDebut":"2018-10-01T00:00:00.000+0000",
         "etat":"payé"
      }
   ],
   "Ash Moon":[  
      {  
         "dateDebut":"2018-10-01T00:00:00.000+0000",
         "etat":"payé"
      }
   ]
}

ストリームの使用の初心者として、私はいくつかの調査を行い、そのようなコードをいくつか見つけました

Map<String, List<Map>> afterFormatting =
        beforeFormatting.stream()
                .flatMap(m -> m.entrySet().stream())
                .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));

しかし、それは私にとっては仕事をしません

6
Wassim Makni

あなたが単に探しているようです:

Map<String, List<Map<String, String>>> afterFormatting = 
            beforeFormatting.stream()
                            .collect(Collectors.groupingBy(map -> map.get("nom")));

または、それぞれが必要ない場合はMap<String, String>「nom」エントリを含む結果セットでは、次のように実行できます。

Map<String, List<Map<String, String>>> afterFormatting = 
     beforeFormatting.stream()
                     .collect(Collectors.groupingBy(map -> map.get("nom"), 
                           Collectors.mapping(map -> { 
                                Map<String, String> temp = new HashMap<>(map);
                                temp.remove("nom");
                               return temp;
                     }, Collectors.toList())));
5
Aomine

私があなたが正しいと理解しているなら、あなたは次のような地図を持っています

_{
        "dateDebut": "2018-07-01T00:00:00.000+0000",
        "nom": "Julien Mannone",
        "etat": "Impayé"
      },
_

しかし、あなたが電話するとき

.flatMap(m -> m.entrySet().stream())すべてのマップのすべてのエントリセットのストリームを取得します。しかし実際には、あなたの地図は地図そのものではありません。それらはむしろPOJOオブジェクトです。

次のようなクラスを作成することをお勧めします

_class Value {
String dateDebut, String nom, Etring etat;
// constructor
}
_

次に、各マップをこのクラスに変換します。

_beforeFormatting.stream()
.map(m-> new Value(m.get("dateDebut"), m.get("nom"),m.get("etat"))
_

これで、_stream<Value>_が作成され、 "nom"で簡単にグループ化できます。

_.collect(groupingBy(Value::getNom)
_
1
dehasi

mapストリームしてフォーマットを必要に変更してから、以下を収集する必要があります。

list.stream().map(it -> {
                Map<String, Map<String, String>> newMap = new HashMap<>();
                String nom = it.get("nom");
                it.remove("nom");
                newMap.put(nom, it);
                return newMap;
            }
    ).collect(Collectors.toList())

テスト可能なコード:

    Map<String, String> m = new HashMap<>();
    m.put("dateDebut", "2018-07-01T00:00:00.000+0000");
    m.put("nom", "Julien Mannone");
    m.put("etat", "Impayé");

    Map<String, String> m2 = new HashMap<>();
    m2.put("dateDebut", "2018-10-01T00:00:00.000+0000");
    m2.put("nom", "Mathiew Matic");
    m2.put("etat", "payé");

    Map<String, String> m3 = new HashMap<>();
    m3.put("dateDebut", "2018-07-01T00:00:00.000+0000");
    m3.put("nom", "Ash Moon");
    m3.put("etat", "payé");

    List<Map<String, String>> list = new ArrayList<>();
    list.add(m);
    list.add(m2);
    list.add(m3);

    List<Map<String, Map<String, String>>> res = list.stream().map(it -> {
                Map<String, Map<String, String>> newMap = new HashMap<>();
                String nom = it.get("nom");
                it.remove("nom");
                newMap.put(nom, it);
                return newMap;
            }
    ).collect(Collectors.toList());

    System.out.println(res);
1
user987339