Skip to content

Lambda for comparing two lists of map id fields for missing ids

I have two lists of maps, and each map as an id field. I need to compare these two lists against one another to find missing ids from collectionB (“7777” in the below)

    List<Map<String, Object>> collectionA = new ArrayList<Map<String, Object>>() {{
        add(new HashMap<String, Object>() {{ put("id", "5555"); }});
        add(new HashMap<String, Object>() {{ put("id", "6666"); }});
        add(new HashMap<String, Object>() {{ put("id", "7777"); }});
        add(new HashMap<String, Object>() {{ put("id", "8888"); }});
    }};

    List<Map<String, Object>> collectionB = new ArrayList<Map<String, Object>>() {{
        add(new HashMap<String, Object>() {{
            add(new HashMap<String, Object>() {{ put("id", "5555"); }});
            add(new HashMap<String, Object>() {{ put("id", "6666"); }});
            add(new HashMap<String, Object>() {{ put("id", "8888"); }});
        }});
    }};

I am really looking to learn more about stream() so any help with this would be appreciated. As you can tell I am not really sure where to start with this:

I started going down this path but it seems like it is not the right approach.

    List<String> bids = collectionB.stream()
        .map(e -> e.entrySet()
            .stream()
            .filter(x -> x.getKey().equals("id"))
            .map(x -> x.getValue().toString())
            .collect(joining("")
        )).filter(x -> StringUtils.isNotEmpty(x)).collect(Collectors.toList());

I guess this gets me to two lists of strings I can compare but it seems like this isn’t the optimal approach. Any help is appreciated.

Answer

If you want to filter Map of items from collectionA which are not present in collectionB, iterate collectionA and check for each entry is present in any of the Map in collectionB, and finally collect entry into Map which is not present in collectionB

List<Map<String,String>> results = collectionA.stream()
    .flatMap(map->map.entrySet().stream())
    .filter(entry->collectionB.stream().noneMatch(bMap->bMap.containsValue(entry.getValue())))
    .map(entry-> Collections.singletonMap(entry.getKey(),entry.getValue()))
    .collect(Collectors.toList());