Java8连接两个映射列表

Java8连接两个映射列表,java,dictionary,join,merge,java-stream,Java,Dictionary,Join,Merge,Java Stream,Java8中是否有任何方法使用Streams API连接两个映射列表? 假设我有: 清单1 [ { id=1, attr1='a', attr2='b' }, { id=2, attr1='c', attr2='d' }, { id=3, attr1='e', attr2='f' } ] 清单2 [ { id=1, attr3='x', attr4='y'

Java8中是否有任何方法使用Streams API连接两个映射列表? 假设我有:

清单1

[  
   {  
      id=1, attr1='a', attr2='b'
   },
   {  
      id=2, attr1='c', attr2='d'
   },
   {  
      id=3, attr1='e', attr2='f'
   }
]
清单2

[  
       {  
          id=1, attr3='x', attr4='y'
       },
       {  
          id=2, attr3='x', attr4='z'
       },
       {  
          id=3, attr3='z', attr4='y'
       }
    ]
现在我想通过键ID连接这两个列表,只需列出一个SQL连接, 产出将是:

[  
       {  
          id=1, attr1='a', attr2='b', attr3='x', attr4='y'
       },
       {  
          id=2, attr1='c', attr2='d', attr3='x', attr4='z'
       },
       {  
          id=3, attr1='e', attr2='f', attr3='z', attr4='y'
       }
    ]

非常感谢

有很多方法,有流也有无流。最好的方法取决于更精确的输入要求,而您还没有给我们。以下内容适用于您问题中的示例列表:

    if (list1.size() != list2.size()) {
        throw new IllegalStateException("Lists don’t match, not same size");
    }

    List<Map<String, Character>> comnbinedList = IntStream.range(0, list1.size())
            .mapToObj(i -> {
                    Map<String, Character> m1 = list1.get(i);
                    Character id1 = m1.get("id");
                    Map<String, Character> m2 = list2.get(i);
                    Character id2 = m1.get("id");
                    if (! id1.equals(id2)) {
                        throw new IllegalStateException("Lists don’t match, id " + id1 + " != " + id2);
                    }
                    HashMap<String, Character> mergedMap = new HashMap<>(m1);
                    mergedMap.putAll(m2);
                    return mergedMap; 
                })
            .collect(Collectors.toList());

当然,您需要将id声明为常量。

有很多方法,有流和无流。最好的方法取决于更精确的输入要求,而您还没有给我们。以下内容适用于您问题中的示例列表:

    if (list1.size() != list2.size()) {
        throw new IllegalStateException("Lists don’t match, not same size");
    }

    List<Map<String, Character>> comnbinedList = IntStream.range(0, list1.size())
            .mapToObj(i -> {
                    Map<String, Character> m1 = list1.get(i);
                    Character id1 = m1.get("id");
                    Map<String, Character> m2 = list2.get(i);
                    Character id2 = m1.get("id");
                    if (! id1.equals(id2)) {
                        throw new IllegalStateException("Lists don’t match, id " + id1 + " != " + id2);
                    }
                    HashMap<String, Character> mergedMap = new HashMap<>(m1);
                    mergedMap.putAll(m2);
                    return mergedMap; 
                })
            .collect(Collectors.toList());

当然,您需要声明id为常量。

在map中使用id键的数据结构;这有点不寻常,但这里有一个流收集器的例子。因为你们的映射值都是int和String,所以我使用了map


在地图中使用id键的数据结构;这有点不寻常,但这里有一个流收集器的例子。因为你们的映射值都是int和String,所以我使用了map


你试了什么?这不是一个代码编写服务。它看起来很像Javascript,但可能只是伪代码然而,映射在实际的Java代码中是什么样子的?我假设id是键,但是第一个列表中的attrib1和attrib2是什么?值对象的属性?嵌套集合中的元素?可以在java 8中进行集合连接。参考请解决您的问题。@Thomas抱歉,我没有说此结构表示映射列表,id、attr1、attr2、attr3和attr4是键。这是否意味着您映射的键类型是字符串?值类型,是整数、字符、对象还是什么?此外,在您的示例中,是否需要列表来保存具有相同id值1、2和3的地图?如果其中一个列表中有一张“额外”的地图怎么办?它们的顺序是一样的吗?你试了什么?这不是一个代码编写服务。它看起来很像Javascript,但可能只是伪代码然而,映射在实际的Java代码中是什么样子的?我假设id是键,但是第一个列表中的attrib1和attrib2是什么?值对象的属性?嵌套集合中的元素?可以在java 8中进行集合连接。参考请解决您的问题。@Thomas抱歉,我没有说此结构表示映射列表,id、attr1、attr2、attr3和attr4是键。这是否意味着您映射的键类型是字符串?值类型,是整数、字符、对象还是什么?此外,在您的示例中,是否需要列表来保存具有相同id值1、2和3的地图?如果其中一个列表中有一张“额外”的地图怎么办?它们的顺序一样吗?
import java.util.*;
public class JoinTwoListofMaps {
    public static void main(String... args){
        List<Map<String, Object>> list1 = new ArrayList<>();
        List<Map<String, Object>> list2 = new ArrayList<>();
        Map<String, Object> map1_1 = new HashMap<>();
            map1_1.put("id",1);
            map1_1.put("attr1","a");
            map1_1.put("attr2","b");
        list1.add(map1_1);
        Map<String, Object> map2_1 = new HashMap<>();
            map2_1.put("id",1);
            map2_1.put("attr3","x");
            map2_1.put("attr4","y");
        list2.add(map2_1);
        System.out.println(joinTwoListOfMaps(list1, list2));
    }
    @SafeVarargs
    public static List<Map<String, Object>> joinTwoListOfMaps(List<Map<String, Object>>... listsOfMaps){
        List<Map<String, Object>> finalList = Arrays.stream(listsOfMaps).collect(ArrayList::new, List::addAll, List::addAll);
        return finalList.stream().collect(ArrayList::new, (list, mapToMerge) ->{
            Optional<Map<String, Object>> mapWithSameID = list.stream()
                    .filter(map -> map.get("id").equals(mapToMerge.get("id"))).findFirst();
            if (mapWithSameID.isPresent()) mapWithSameID.get().putAll(mapToMerge);
            else list.add(mapToMerge);
        }, ArrayList::addAll);
    }
}
final List<HashMap<String, String>> joinedById = list1.stream()
            .flatMap(m1 -> list2.stream()
                    .filter(y -> m1.get("id").equals(y.get("id")))
                    .map(m2 -> new HashMap<String, String>() {{
                        putAll(m1);
                        putAll(m2);
                    }}))
            .collect(Collectors.toList());