将部分哈希图重复项合并到Java中的新arraylist

时间:2019-04-26 06:30:54

标签: java java-8 java-stream

我有Stream<Map<String, String>>,其中每个地图就像一个单独的记录,并且包含两个条目:

  1. 汽车ID(“ ID”,“ 1003”)
  2. 公里(“ KMI”,“ 500”)

此列表可能包含重复的地图,其方式是2张或多张地图可能具有相同的car ID输入值。 基本上是这样的:entry1.get(“ ID”)== entry2.get(“ ID”)。我想做的是删除具有重复ID的地图,然后将KMI值合并在一起。 这个:

  

{“ ID”:“ 1003”,“ KMI”:“ 500”},{“ ID”:“ 1003”,“ KMI”:“ 400”},   {“ ID”:“ 1004”,“ KMI”:“ 200”}

应该变成这样:

  

{“ ID”:“ 1003”,“ KMI”:“ 900”},{“ ID”:“ 1004”,“ KMI”:“ 200”}

我曾尝试单独使用流API来执行此操作,但我对此一无所知。我试图修改一个具有对象列表的类似示例 这是到目前为止我得到的:

List<Map<String, String>> result = new ArrayList<>(
    queryKmAll.collect(
        Collectors.toMap(a1 -> a1.get("ID")), Function.identity(), (Map<String, String> m2, Map<String, String> m1) -> {
            m1.put("KMI", String.valueOf(Double.parseDouble(m1.get("KMI")) + Double.parseDouble(m2.get("KMI"))));

            return m1;
        })
    )
);

3 个答案:

答案 0 :(得分:2)

我从OP离开的地方接了。我对您的逻辑做了一些修改,以返回您想要的内容。看看它。希望对您有帮助

Collectors.toMap将返回一个以ID作为键,以sum of KMI作为Function.identity()情况的地图。因此,返回值为Map<Object,Map<String,String>>。因为预期的输出为Stream<Map<String,String>,所以我添加了.values().stream()

Stream<Map<String, String>> result = queryKmAll.collect(Collectors.toMap(a1 -> a1.get("ID"),
            Function.identity(), (Map<String, String> m2, Map<String, String> m1) -> {
                m1.put("KMI",
                        String.valueOf(Double.parseDouble(m1.get("KMI")) + Double.parseDouble(m2.get("KMI"))));

                return m1;
            })).values().stream();

result.forEach(System.out::println);

答案 1 :(得分:1)

您要寻找的是Collectors.groupingBy

    Map<String, Long> summary = Stream
        .of(
            new HashMap<String, String>() {{
              put("ID", "1003");
              put("KMI", "500");
            }},
            new HashMap<String, String>() {{
              put("ID", "1003");
              put("KMI", "400");
            }},
            new HashMap<String, String>() {{
              put("ID", "1004");
              put("KMI", "200");
            }}
        )
        .collect(Collectors.groupingBy(
            m -> m.get("ID"),
            Collectors.summingLong(m -> Long.valueOf(m.get("KMI")))
        ));

    System.out.println(summary);

此外,您可以将地图替换为一个类,例如Summary

  public class Summary {

    public Summary(String id, Long kmi) {
      this.id = id;
      this.kmi = kmi;
    }

    private String id;
    private Long kmi;

    public String getId() {
      return id;
    }

    public Long getKmi() {
      return kmi;
    }
  }

然后使用:

    Map<String, Long> summary = Stream
        .of(
            new Summary("1003", 500L),
            new Summary("1003", 400L),
            new Summary("1004", 200L)
        )
        .collect(Collectors.groupingBy(
            s -> s.getId(),
            Collectors.summingLong(s -> s.getKmi())
        ));

    System.out.println(summary);

打印: {1004=200, 1003=900}

答案 2 :(得分:1)

您首先需要按ID分组,然后在每个组中添加KMI:

// stream is your initial stream
List<Map<String, String>> list = stream.collect(Collectors.groupingBy(x -> x.get("ID")))
        .entrySet().stream().map(x -> {
            List<Map<String, String>> value = x.getValue();
            int kmSum = value.stream().mapToInt(y -> Integer.parseInt(y.get("KMI"))).sum();
            HashMap<String, String> map = new HashMap<>();
            map.put("ID", x.getKey());
            map.put("KMI", Integer.toString(kmSum));
            return map;
        }).collect(Collectors.toList());