我正在编写一些java代码,它应该解析具有不同列类型和值的csv文件。基本文件看起来像这样(CSV),没有标题/列行。为了使处理文件时更简单,我希望能够使用列名访问每个单元格的索引值。 目前我不想使用CSV解析器。
Column1 | Column2 | Column3 |...
--------+---------+---------+---
val10 | val20 | val30 |
val11 | val21 | val31 |
val12 | val22 | val32 |
... | ... | ... |
我考虑过使用列名的ArrayList(按顺序),因为枚举不像C ++那样转换回整数。这样我可以做类似的事情:
ArrayList<String> columnNames = new ArrayList<String>();
columnNames.add("Column1");
columnNames.add("Column2");
columnNames.add("Column3");
// read each line from the file ...
String[] row = line.trim().split(",");
String col2 = row[ columnNames.indexOf("Column2") ];
我是Java的新手 - 有更好/更聪明的方法吗?感谢。
答案 0 :(得分:2)
您的代码有效。但是,如果你正在寻找“更好”的方式,你可能需要重新考虑两点:
List的indexOf(object)方法不是那么快。费用O(n)。如果你保持Map<columnNameString, indexNumber>
,并从colName获取索引,它应该比你当前的impl更快。除此之外,在java中,您可以从枚举中获得不同类型的值。你甚至可以让你的枚举实现接口。
你应该做一些异常处理。如果文件中的一行缺少(或更多)列,该怎么办?您当前的代码将抛出OutOfbound异常。但是我希望这已经在您的真实代码中完成了。
答案 1 :(得分:1)
解决此问题的最简单方法是使用集合库并创建一个地图列表,其中地图中的键是列名,如下所示:
List<Map<String,String>> records = someCodeForReadingDataFromFile();
将每一行拆分为数组,然后创建值的映射:
List<Map<String,String>> someCodeForReadingDataFromFile() {
List<<Map<String,String>> rowsList = new LinkedList<<Map<String,String>>();
final String[] columnNames = {"Column1", "Column2", "Column3"};
// add some loop to read one line at the time from the file
...
String[] rows = line.trim().split(",");
Map<String, String> rowMap = new HashMap<String, String>();
for(int columnIndex = 0; columnIndex < columnNames.length; columnIndex++) {
rowMap.put(columnNames[columnIndex], rows[columnIndex]);
}
rowsList.add(rowMap);
// repeat this until you reach EOF
return rowsList;
}
然后,您可以访问CSV文件中的所有单元格的行索引和列名称:
String valueOne = records.get(0).get("Column1"); // will set the value to "val10"
如果列名已修复,您仍然可以创建一个枚举,例如
public enum Columns {
Column1, Column2;
}
然后使用从Enum类继承的name()方法来获取值:
String valueOne = records.get(0).get(Columns.Column1);
但是,如果你决定使用库来简化这个过程,我真的可以推荐Smooks library甚至Apache Commons CSV(非常轻量级!)。
答案 2 :(得分:1)
你的一个断言是不准确的。你声明“枚举不会像在C ++中那样转换回整数”,这是真的。但是,Java中的Enums实际上比这更灵活!它们是对象,您可以拥有任意数量的值或属性,而不仅仅是数字。考虑这个(未经测试的)代码:
public enum ColumnEnum {
COL1(1),
COL2(2),
COL3(3);
private final int index;
ColumnEnum(int index) {
this.index = index;
}
public double index() { return index; }
}
现在您可以像这样引用数组的部分:
// read each line from the file ...
String[] row = line.trim().split(",");
String col2 = row[ ColumnEnum.COL1.index() ];