使用Java8 Stream API合并两个哈希图列表

时间:2018-08-09 05:29:10

标签: java collections java-8 java-stream

我有List个中的两个HashMap

List<HashMap<String,String>> a = new ArrayList<HashMap<String,String>>();
List<HashMap<String,String>> b = new ArrayList<HashMap<String,String>>();

样本数据:

a = [{a1=1, b1=2, c=3},{a2=4, b2=5, c=6}]
b = [{d1=7,c=3},{d2=8,c=6}]

我想使用具有输出的Stream API合并两个List,并在List中拥有最后一个HashMap

c = [{a1=1, b1=2, c=3, d1=7},{a2=4, b2=5, c=6, d2=8}]

有帮助吗?

3 个答案:

答案 0 :(得分:2)

有时候,Stream API并不是答案。在这种情况下,规则循环将更具可读性和可维护性。您甚至可以在循环中添加注释,以解释为什么这样做而不会使代码不可读。 Stream API使平凡的事情变得非常容易,而复杂的事情则变得更加复杂。

除非这是一项家庭作业,否则它是一个愚蠢的作业。学业不应该鼓励学生在错误的地方使用愚蠢的构造。

在现实世界中,可读性和可维护性对于行数或机灵性得分至关重要。

答案 1 :(得分:1)

如果您根据List的索引合并它们,并且两个List的长度相同,则可以编写:

IntStream.range(0,a.size()).forEach(i->a.get(i).putAll(b.get(i)));

这将导致List a包含合并结果。

如果您想产生一个新的List而不改变原始的List,则可以创建新的HashMap并将它们收集到一个新的List中:

List<HashMap<String,String>> c =
    IntStream.range(0,a.size())
             .mapToObj(i -> {
                        HashMap<String,String> hm = new HashMap<>(a.get(i)); 
                        hm.putAll(b.get(i)); 
                        return hm;
                      })
             .collect(Collectors.toList());

编辑更新的问题:

List<HashMap<String,String>> c =
    a.stream ()
     .map(am -> {
             HashMap<String,String> hm = new HashMap<>(am);
             HashMap<String,String> second =
               b.stream()
                .filter (bm -> bm.get ("c") != null && bm.get ("c").equals (am.get ("c")))
                .findFirst()
                .orElse(null);
             if (second != null) {
               hm.putAll (second);
             }
             return hm;
          })
    .collect(Collectors.toList());

现在,我们在第一个List的元素上进行流式传输,并为每个HashMap搜索第二个HashMap中对应的List

答案 2 :(得分:0)

尝试这样。为了简化它,我定义了一个Bifunction。

BiFunction<HashMap<String, String>, List<HashMap<String, String>>, HashMap<String, String>> biFunction =
            (m1, listOfMap) -> {
                HashMap<String, String> result = new HashMap<>(m1);
                listOfMap.forEach(item -> {
                    if (item.containsKey("c")&& item.get("c").equals(result.get("c")))
                    result.putAll(item);
                });
                return result;
            };

然后合并,请使用此BiFunction合并列表项。

IntStream.range(0, list.size())
            .mapToObj(i -> biFunction.apply(list.get(i), list2))
            .collect(Collectors.toList());