代码之家  ›  专栏  ›  技术社区  ›  TrongBang

Java 8 Stream如何将2个大小不等的列表与自定义逻辑合并以拾取重复项

  •  2
  • TrongBang  · 技术社区  · 7 年前

     "list1": [
        {
          "partyId": "1",
          "accountId": "1",
          "sourceSystem": "1",
        },
        {
          "partyId": "2",
          "accountId": "2",
          "sourceSystem": "2",
        }]
    

     "list2": [
        {
          "partyId": "3",
          "accountId": "3",
          "sourceSystem": "3",
        },
        {
          "partyId": "1",
          "accountId": "2",
          "sourceSystem": "2",
        }]
    

    现在我需要合并list1和list2来获得这个输出。

     "merged": [
        {
          "partyId": "1",
          "accountId": "1",
          "sourceSystem": "1",
        },
        {
          "partyId": "2",
          "accountId": "2",
          "sourceSystem": "2",
        },
        {
          "partyId": "3",
          "accountId": "3",
          "sourceSystem": "3",
        }]
    

    您可以看到它合并了列表1和列表2中的1、2和3。另外,由于列表2中有一个partyId=1(也在列表1中),但详细信息(accountId和sourceSystem)不同,因此选择了列表1中的partyId=1。

    如何使用Java8流实现这一点?或者,唯一的方法是将它们转换为java对象并执行for循环。

    3 回复  |  直到 7 年前
        1
  •  4
  •   Ravindra Ranwala    7 年前

    你可以一次就这么做,

    List<Map<String, String>> resultMap = Stream.concat(mapListOne.stream(), mapListTwo.stream())
        .collect(Collectors.groupingBy(m -> m.get("partyId"), Collectors.toList()))
        .entrySet().stream()
        .map(e -> e.getValue().get(0))
        .collect(Collectors.toList());
    

    这是一个两步计算,首先计算 List 每个partyId值作为映射,然后获取每个partyId上的第一个元素 计算最终结果。

        2
  •  1
  •   Naman    7 年前

    一种方法是迭代第一个列表,并使用 partyId 作为 key Party value :

    Map<String, CustomObject> customObjectMap = customObjectList1.stream()
            .collect(Collectors.toMap(CustomObject::getPartyId, customObject -> customObject, (a, b) -> b));
    

    然后遍历第二个列表并过滤现有的partyID

    customObjectList2.stream()
            .filter(customObject -> !customObjectMap.containsKey(customObject.getPartyId()))
            .forEach(customObject -> customObjectMap.put(customObject.getPartyId(), customObject));
    

    values 作为最终输出从映射中删除

    List<CustomObject> merged = new ArrayList<>(customObjectMap.values());
    

    Set 键盘上的钥匙 partyId 来自列表1

    Set<String> partyIds = customObjectList1.stream().map(CustomObject::getPartyId).collect(Collectors.toSet());  // set assuming a list wouldn't have duplicate partyId
    

    然后根据现有关键帧从另一个列表中删除对象

    customObjectList2.removeIf(p -> partyIds.contains(p.getPartyId()));
    

    最后将所有对象添加到一个对象列表中

    customObjectList1.addAll(customObjectList2); // customObjectList1 is now your 'merged'
    
        3
  •  0
  •   sprinter    7 年前

    如果逻辑只是第一个列表中的所有项目加上第二个列表中与第一个列表中的项目不匹配的所有项目,则:

    List<Map<String,String>> result = Stream.concat(list1.stream(),
        list2.stream().filter(m2 -> list1.stream()
            .noneMatch(m1 -> m1.get("partyId").equals(m2.get("partyId"))))
        .collect(Collectors.toList());
    
    推荐文章