簡體   English   中英

通過流將地圖列表轉換為單個地圖

[英]Convert List of Maps to single Map via streams

我在數據庫中查詢兩列,其中第一列是第二列的鍵。 如何將結果列表轉換為單個地圖? 甚至有可能嗎? 我剛剛看到了豆類的例子。

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")));

您忘記將鍵和值映射轉換為生成String

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

完整示例

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;
}

哪個打印

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

問題是你有一個地圖列表。 下面的代碼應該工作:

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())));
});

如果我們嘗試運行這個例子

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);

它很高興地為我們提供了這樣的輸出:

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

加上上面 esin88 所說的,如果我們有可能在映射列表中得到重復的鍵,我們希望得到一個帶有鍵和值列表而不是鍵值對的映射,可以像下面那樣完成。

    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;
}

結果看起來像

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

我們可以使用 java 流的 reduce() 將映射列表轉換為 java 中的單個映射。

請檢查以下代碼以了解它的使用方式。

例如:

@Data
@AllArgsConstructor
public class Employee {

    private String employeeId;
    private String employeeName;
    private Map<String,Object> employeeMap;
}


public class Test{
 public static void main(String[] args) {
 
        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Map<String, Object> map3 = new HashMap<>();
        
        
        map1.put("salary", 1000);
        Employee e1 = new Employee("e1", "employee1", map1);

        map2.put("department", "HR");
        Employee e2 = new Employee("e2", "employee2", map2);

        map3.put("leave balance", 14);
        Employee e3 = new Employee("e3", "employee3", map3);
        
        //now we create a employees list and add the employees e1,e2 and e3.
        List<Employee> employeeList = Arrays.asList(e1,e2,e3);
         
        //now we retreive employeeMap from all employee objects and therefore have a List of employee maps.
        List<Map<String, Object>> employeeMaps = employeeList
        .stream()
        .map(Employee::getEmployeeMap)
        .collect(Collectors.toList());

        System.out.println("List of employee maps: " + employeeMaps);
        
        // to reduce a list of maps to a single map, we use the reduce function of stream.
        
        Map<String, Object> finalMap = employeeMaps
        .stream()
        .reduce((firstMap, secondMap) -> {
                firstMap.putAll(secondMap);
                 return firstMap;
              }).orElse(null);
               
        System.out.println("final Map: "+ finalMap);             
        
}
}

輸出:員工映射列表:[{salary=1000}, {department=HR}, {leave balance=14}]。

最終地圖:{salary=1000,部門=HR,休假余額=14}

PS:為擴展答案道歉,這是我第一次使用 stackoverflow。 謝謝 :-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM