Convert List of Maps to single Map via streams

南楼画角 提交于 2020-05-23 03:32:07

问题


I query the DB for two columns where the first one is the key to the second one. How can I convert the resulting list to a single map? Is it even possible? I have just seen examples with beans.

List<Map<String, Object>> steps = jdbcTemplate.queryForList("SELECT key, value FROM table");

// well this doesn't work
Map<String, String> result = steps.stream().collect(Collectors.toMap(s -> s.get("key"), s -> s.get("value")));

回答1:


You forgot to convert your key and value mappings to produce String:

final Map<String, String> result = steps
                .stream()
                .collect(Collectors.toMap(s -> (String) s.get("key"), s -> (String) s.get("value")));

Full example

public static void main(String[] args) {
    final List<Map<String, Object>> steps = queryForList("SELECT key, value FROM table");
    final Map<String, String> result = steps
            .stream()
            .collect(Collectors.toMap(s -> (String) s.get("key"), s -> (String) s.get("value")));
    result.entrySet().forEach(e -> System.out.println(e.getKey() + " -> " + e.getValue()));
}

private static List<Map<String, Object>> queryForList(String s) {
    final List<Map<String, Object>> result = new ArrayList<>();

    for (int i = 0; i < 10; i++) {
        final Map<String, Object> map = new HashMap<>();
        map.put("key", "key" + i);
        map.put("value", "value" + i);
        result.add(map);
    }

    return result;
}

Which prints

key1 -> value1
key2 -> value2
key0 -> value0
key5 -> value5
key6 -> value6
key3 -> value3
key4 -> value4
key9 -> value9
key7 -> value7
key8 -> value8



回答2:


The problem is you have a list of maps. The code below should work:

Map<String, String> result = new HashMap<>();
steps.stream().forEach(map -> {
    result.putAll(map.entrySet().stream()
        .collect(Collectors.toMap(entry -> entry.getKey(), entry -> (String) entry.getValue())));
});

If we try to run this example

Map<String, Object> steps1 = new HashMap<>();
steps1.put("key11", "value11");
steps1.put("key12", "value12");

Map<String, Object> steps2 = new HashMap<>();
steps2.put("key21", "value21");
steps2.put("key22", "value22");

List<Map<String, Object>> steps = new ArrayList<>();
steps.add(steps1);
steps.add(steps2);

Map<String, String> result = new HashMap<>();
steps.stream().forEach(map -> {
    result.putAll(map.entrySet().stream()
        .collect(Collectors.toMap(entry -> entry.getKey(), entry -> (String) entry.getValue())));
});
System.out.println(result);

It happily gives us the output like that:

{key12=value12, key11=value11, key22=value22, key21=value21}



回答3:


Adding on to what esin88 said above, if there is a possibility that we get duplicate keys in the list of maps, we would like to get a map with key and list of values rather than key value pair which can be done like below.

    public static void main(String[] args) {
    final List<Map<String, Object>> steps = queryForList("SELECT key, value FROM table");
    /*final Map<String, String> result = steps.stream()
            .collect(Collectors.toMap(s -> (String) s.get("key"), s -> (String) s.get("value")));*/
    final Map<String, List<String>> result1 = steps.stream()
            .collect(Collectors.groupingBy(k -> String.valueOf(k.get("key")),
                    Collectors.mapping(l -> String.valueOf(l.get("value")), Collectors.toList())));
    result1.entrySet().forEach(e -> System.out.println(e.getKey() + " -> " + e.getValue()));
}

private static List<Map<String, Object>> queryForList(String s) {
    final List<Map<String, Object>> result = new ArrayList<>();
    Map<String, Object> map = new HashMap<>();
    for (int i = 0; i < 10; i++) {
        map = new HashMap<>();
        map.put("key", "key" + i);
        map.put("value", "value" + i);
        result.add(map);
    }
    map = new HashMap<>();
    map.put("key", "key1");
    map.put("value", "value20");
    result.add(map);

    return result;
}

The result would look like

key1 -> [value1, value20]
key2 -> [value2]
key0 -> [value0]
key5 -> [value5]
key6 -> [value6]
key3 -> [value3]
key4 -> [value4]
key9 -> [value9]
key7 -> [value7]
key8 -> [value8]


来源:https://stackoverflow.com/questions/42490314/convert-list-of-maps-to-single-map-via-streams

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!