如何通过lambda表达式将List<List>转换为ArrayList<HashMap>
问题修复方案
1. CSV读取代码问题&修复
原代码问题:
- 递归实现逻辑错误:每次调用
readWholeFile都会新建独立的rows集合,上一轮读取添加的行数据不会被保留 finally代码块强制返回当前方法的rows对象,直接覆盖了递归调用返回的结果,最终只会拿到空集合或者最多一行数据
修复后代码:
// 从CSV文件导入数据 private static List<List<String>> readWholeFile(BufferedReader br) throws IOException { List<List<String>> rows = new ArrayList<>(); String line; // 改用循环读取,避免递归逻辑错误 while ((line = br.readLine()) != null) { List<String> row = Arrays.asList(line.split(",")); rows.add(row); } return rows; }
如果一定要用递归实现,需要把rows作为参数传递到递归方法中,避免每次新建集合。
2. 集合转换代码问题&修复
原代码问题:
- 方法参数为
columns,但代码中使用了未定义的keys变量,属于笔误 - Stream流是惰性求值的,仅调用
map属于中间操作,不会触发实际执行,因此eleMap.put代码根本没有运行,最终map为空 - 全局只创建了一个
eleMap对象,就算代码跑通,所有行的数据都会往同一个map里塞,后一行的数据会覆盖前一行 - 用
row.indexOf(ele)获取索引效率极低,且如果行内有重复值,会拿到错误的索引位置
修复后代码:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; // 将List<List>转换为ArrayList<HashMap> private static ArrayList<HashMap<String, String>> putRowIntoMap(List<List<String>> rows, List<String> columns) { return rows.stream() .map(row -> { HashMap<String, String> eleMap = new HashMap<>(); // 直接按索引遍历匹配列名,避免查索引的开销和错误 for (int i = 0; i < columns.size() && i < row.size(); i++) { eleMap.put(columns.get(i), row.get(i)); } return eleMap; }) .collect(Collectors.toCollection(ArrayList::new)); }
如果偏好纯Stream实现,写法如下:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; private static ArrayList<HashMap<String, String>> putRowIntoMap(List<List<String>> rows, List<String> columns) { return rows.stream() .map(row -> IntStream.range(0, Math.min(columns.size(), row.size())) .collect( HashMap::new, (map, idx) -> map.put(columns.get(idx), row.get(idx)), HashMap::putAll ) ) .collect(Collectors.toCollection(ArrayList::new)); }
内容的提问来源于stack exchange,提问作者WohKX
相关产品推荐
相关产品推荐

