使用流在Java 8中按Map值分组

时间:2018-10-19 08:56:03

标签: java java-8 java-stream grouping

我有一个Map列表,我想使用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())));

但这对我没有帮助

3 个答案:

答案 0 :(得分:5)

似乎只是在寻找:

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

答案 1 :(得分:1)

如果我了解您的意见,您将拥有

这样的地图
{
        "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)

答案 2 :(得分:1)

您只需要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);