Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过流将地图列表转换为单个地图_Java_Java 8_Java Stream - Fatal编程技术网

Java 通过流将地图列表转换为单个地图

Java 通过流将地图列表转换为单个地图,java,java-8,java-stream,Java,Java 8,Java Stream,我在DB中查询两列,其中第一列是第二列的键。 如何将结果列表转换为单个映射? 有可能吗?我刚刚看到了一些关于豆子的例子 List<Map<String, Object>> steps = jdbcTemplate.queryForList( "SELECT key, value FROM table"); // well this doesn't work Map<String, String> result = step

我在DB中查询两列,其中第一列是第二列的键。 如何将结果列表转换为单个映射? 有可能吗?我刚刚看到了一些关于豆子的例子

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")));
List steps=jdbcTemplate.queryForList(
“选择键,从表中选择值”);
//这个不行
Map result=steps.stream()
.collect(Collectors.toMap(s->s.get(“key”)、s->s.get(“value”));

您忘记将键和值映射转换为生成
字符串

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

问题是你有一个地图列表。下面的代码应该有效:

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

再加上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;
}
我们可以使用java streams的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);             
        
}
}
@数据
@AllArgsConstructor
公营雇员{
私有字符串employeeId;
私有字符串employeeName;
私人地图员工地图;
}
公开课考试{
公共静态void main(字符串[]args){
Map map1=新的HashMap();
Map map2=新的HashMap();
Map map3=新的HashMap();
map1.put(“工资”,1000);
员工e1=新员工(“e1”,“员工1”,map1);
map2.put(“部门”、“人力资源”);
雇员e2=新雇员(“e2”,“雇员2”,map2);
map3.put(“剩余余额”,14);
员工e3=新员工(“e3”,“员工3”,map3);
//现在我们创建一个员工列表并添加员工e1、e2和e3。
List employeeList=Arrays.asList(e1、e2、e3);
//现在,我们从所有employee对象检索employeeMap,因此有一个employee映射列表。
List employeeMaps=员工列表
.stream()
.map(Employee::getEmployeeMap)
.collect(Collectors.toList());
System.out.println(“员工地图列表:“+employeeMaps”);
//为了将映射列表简化为单个映射,我们使用了stream的reduce函数。
Map finalMap=员工地图
.stream()
.reduce((第一个映射,第二个映射)->{
firstMap.putAll(secondMap);
返回firstMap;
}).orElse(空);
System.out.println(“最终地图:+finalMap”);
}
}
输出: 员工映射列表:[{salary=1000},{department=HR},{leave balance=14}]

最终映射:{工资=1000,部门=HR,假期余额=14}

PS:很抱歉,这是我第一次来stackoverflow。
谢谢:-)

不幸的是,这行不通。您忘记了这是一个映射列表,它导致java.lang.NullPointerException尝试使用您的确切代码s.get(“key”)的转换不是necessary@user489872不,这是必要的。因为您的初始映射是
map
,所以从该映射中
获取的所有内容都是
对象。如果要创建
映射
,则需要在
toMap
函数中提供两个生成字符串的函数。我的意思是,对于你的
keyMapper
函数
map.get(“key”)
给你一个
对象。如果您想要类型为
String
的密钥,则需要强制转换。如果删除此强制转换,则此示例将不会编译,只是选中了。这不起作用。。因为当您从数据库获取它时,它不仅仅是一个直接的键值对。。每个贴图都有两个键和两个值,这很奇怪。。例如,如果您将其设置为:按emp_ID从员工组中选择emp_ID,max(salary)。。作为回报,你得到的是。。。“emp_ID”->123和“工资”->1000。。所以列表中每个地图的大小是2。。而上面的trik不起作用。@DeepakKumar在我的回答中,到底有什么不起作用?如果你看一下我的
queryForList
方法,你会发现我用2个键值对填充了每个映射,而OP所问的情况并不完全一样。他有一个映射列表,表示数据库中的数据。共有两列:
key
value
,因此该列表中的每个映射只有一个2个条目(一个用于
“key”
键,一个用于
“value”
键)。顺便说一句,在结果映射中没有值,只有映射到键的键,这是没有意义的。你是对的,但只是在关于键的部分。。。Fixing仔细检查了您的“完整示例”。是的,它可以工作,但我没有尝试。它只适用于这种情况,因此我很抱歉,我建议的方法适用于任何地图列表。
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}
    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]
@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);             
        
}
}