如何用Java 8 Stream从String[][]构建Map<String, List<Integer>>?
当然可以用Stream + Collectors API实现!
完全没问题,而且用Stream的写法会更简洁、更符合函数式编程的风格,和你原来的增强for循环逻辑完全等价。
直接上代码实现:
String[][] students = {{"David","50"},{"Sherif","70"},{"Bhavya","85"},{"Bhavya","95"}}; Map<String, List<Integer>> map = Arrays.stream(students) .collect(Collectors.groupingBy( student -> student[0], // 按学生姓名作为分组的Key Collectors.mapping( student -> Integer.parseInt(student[1]), // 将成绩字符串转为Integer类型 Collectors.toList() // 把同一学生的所有成绩收集到List中 ) ));
逻辑拆解:
- 首先用
Arrays.stream(students)把二维数组转换成Stream流; - 调用
collect(Collectors.groupingBy(...))来完成分组:- 第一个参数是分组规则:提取每个数组元素的第一个值(学生姓名)作为Map的Key;
- 第二个参数是下游收集器:先用
mapping把成绩字符串转成Integer,再用toList()把同一Key下的所有成绩收集成List,作为Map的Value。
额外细节:
如果你想明确指定Map的实现类为HashMap(和你原来代码一致),可以用groupingBy的三参数重载版本:
Map<String, List<Integer>> map = Arrays.stream(students) .collect(Collectors.groupingBy( student -> student[0], HashMap::new, // 指定使用HashMap存储结果 Collectors.mapping( student -> Integer.parseInt(student[1]), Collectors.toList() ) ));
不过默认情况下,Collectors.groupingBy已经使用HashMap作为底层存储,所以上面的写法和默认效果一致,只是更显式。
这段代码运行后得到的Map,和你用增强for循环+computeIfAbsent得到的结果完全相同:每个学生姓名对应一个包含其所有成绩的List<Integer>。
内容的提问来源于stack exchange,提问作者Sudarsana Kasireddy
相关产品推荐
相关产品推荐

