[英]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.