如何读取列序随机的CSV文件并将数据存入Java类?
解决方案
核心思路是先建立列名与列索引的映射关系,后续每行数据都通过这个映射找到对应字段的值,再赋值给对象,完全不依赖固定列序。
步骤分解
- 读取CSV首行,拆分得到列名列表,用
HashMap<String, Integer>存储「列名-列索引」的对应关系,比如LabelD对应索引0、LabelA对应索引1等。 - 逐行读取后续数据行,拆分后根据第一步的映射,取出每个目标列(LabelA/LabelB/LabelC/LabelD)对应位置的数据。
- 用取出的数据创建你的数据对象,再将对象存入用于存储的
HashMap(建议用唯一标识作为key,比如行号或某个业务字段)。
代码实现示例
假设你的数据存储类为DataObject,包含labelA、labelB、labelC、labelD四个属性及对应的setter方法:
import java.io.File; import java.util.HashMap; import java.util.Scanner; public class CSVReader { public static void main(String[] args) { // 存储列名到索引的映射 HashMap<String, Integer> columnIndexMap = new HashMap<>(); // 存储每行数据对应的对象,这里用行号作为key,可替换为业务唯一标识 HashMap<Integer, DataObject> dataMap = new HashMap<>(); try (Scanner scanner = new Scanner(new File("your_file.csv"))) { // 解析首行,构建列名-索引映射 if (scanner.hasNextLine()) { String[] headers = scanner.nextLine().split(","); for (int i = 0; i < headers.length; i++) { // 去除列名前后空格,避免匹配失败 String columnName = headers[i].trim(); columnIndexMap.put(columnName, i); } } // 读取并处理数据行 int rowNum = 1; while (scanner.hasNextLine()) { String[] dataValues = scanner.nextLine().split(","); // 跳过空行 if (dataValues.length == 0) continue; DataObject dataObj = new DataObject(); // 根据映射赋值对应字段 if (columnIndexMap.containsKey("LabelA")) { int index = columnIndexMap.get("LabelA"); dataObj.setLabelA(dataValues[index].trim()); } if (columnIndexMap.containsKey("LabelB")) { int index = columnIndexMap.get("LabelB"); dataObj.setLabelB(dataValues[index].trim()); } if (columnIndexMap.containsKey("LabelC")) { int index = columnIndexMap.get("LabelC"); dataObj.setLabelC(dataValues[index].trim()); } if (columnIndexMap.containsKey("LabelD")) { int index = columnIndexMap.get("LabelD"); dataObj.setLabelD(dataValues[index].trim()); } dataMap.put(rowNum, dataObj); rowNum++; } } catch (Exception e) { e.printStackTrace(); } // 验证数据正确性 for (Integer key : dataMap.keySet()) { DataObject obj = dataMap.get(key); System.out.printf("Row %d: %s, %s, %s, %s%n", key, obj.getLabelA(), obj.getLabelB(), obj.getLabelC(), obj.getLabelD()); } } } // 你的数据存储类示例 class DataObject { private String labelA; private String labelB; private String labelC; private String labelD; // Getter & Setter public String getLabelA() { return labelA; } public void setLabelA(String labelA) { this.labelA = labelA; } public String getLabelB() { return labelB; } public void setLabelB(String labelB) { this.labelB = labelB; } public String getLabelC() { return labelC; } public void setLabelC(String labelC) { this.labelC = labelC; } public String getLabelD() { return labelD; } public void setLabelD(String labelD) { this.labelD = labelD; } }
关键注意点
- 如果CSV字段包含逗号(如带引号的复合字段),直接
split(",")会出错,作业场景若未涉及这类情况可忽略;若需处理,可额外判断引号边界(但依赖限制下需自行实现简单逻辑)。 - 需处理数据行与首行列数不一致的情况,可添加
if (index < dataValues.length)判断避免索引越界。 - 始终对列名和数据值做
trim()处理,避免因空格导致映射匹配失败。
内容的提问来源于stack exchange,提问作者DeviceGucci
相关产品推荐
相关产品推荐

