Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.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解析CSV时管理文件列名和位置_Java_Csv_Calculated Columns_File Processing - Fatal编程技术网

使用Java解析CSV时管理文件列名和位置

使用Java解析CSV时管理文件列名和位置,java,csv,calculated-columns,file-processing,Java,Csv,Calculated Columns,File Processing,我正在编写一些java代码,用来解析具有不同列类型和值的csv文件。基本文件类似于(CSV),没有标题/列行。为了简化文件处理过程,我希望能够使用列名访问每个单元格的索引值我现在不想使用CSV解析器 Column1 | Column2 | Column3 |... --------+---------+---------+--- val10 | val20 | val30 | val11 | val21 | val31 | val1

我正在编写一些java代码,用来解析具有不同列类型和值的csv文件。基本文件类似于(CSV),没有标题/列行。为了简化文件处理过程,我希望能够使用列名访问每个单元格的索引值我现在不想使用CSV解析器

    Column1 | Column2 | Column3 |...
    --------+---------+---------+---
    val10   | val20   | val30   |
    val11   | val21   | val31   |
    val12   | val22   | val32   |
    ...     | ...     | ...     |

我考虑使用列名(按顺序排列),因为EnUM不象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") ];
ArrayList columnNames=新建ArrayList();
columnNames。添加(“Column1”);
columnNames。添加(“Column2”);
columnNames。添加(“Column3”);
//读取文件中的每一行。。。
String[]行=line.trim().split(“,”);
字符串col2=行[columnNames.indexOf(“Column2”)];

我对Java相当陌生——有更好/更智能的方法吗?谢谢。

解决此问题的最简单方法是使用集合库并创建地图列表,其中地图中的键是列名,如下所示:

List<Map<String,String>> records = someCodeForReadingDataFromFile();
// read each line from the file ...            
String[] row = line.trim().split(",");            
String col2 = row[ ColumnEnum.COL1.index() ];    
如果列名是固定的,您仍然可以创建这样的枚举

public enum Columns {
 Column1, Column2;
}
然后使用从Enum类继承的name()方法获取值:

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;
}
String valueOne = records.get(0).get(Columns.Column1);

但是,如果您决定使用库来简化此过程,我真的可以推荐or(非常轻量级!)。

解决此问题的最简单方法是使用集合库并创建一个映射列表,其中映射中的键是列名,如下所示:

List<Map<String,String>> records = someCodeForReadingDataFromFile();
// read each line from the file ...            
String[] row = line.trim().split(",");            
String col2 = row[ ColumnEnum.COL1.index() ];    
如果列名是固定的,您仍然可以创建这样的枚举

public enum Columns {
 Column1, Column2;
}
然后使用从Enum类继承的name()方法获取值:

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;
}
String valueOne = records.get(0).get(Columns.Column1);

但是,如果您决定使用一个库来简化这个过程,我真的可以推荐or(非常轻量级!)。

您的一个断言是不准确的。你声明“EnUM不象C++一样转换成整数”,这是真的。然而,Java中的枚举实际上更灵活!它们是对象,可以有任意数量的值或属性,而不仅仅是一个数字。考虑这个(未经测试)代码:

现在,您可以参考阵列的以下部分:

List<Map<String,String>> records = someCodeForReadingDataFromFile();
// read each line from the file ...            
String[] row = line.trim().split(",");            
String col2 = row[ ColumnEnum.COL1.index() ];    

你的一个断言是不准确的。你声明“EnUM不象C++一样转换成整数”,这是真的。然而,Java中的枚举实际上更灵活!它们是对象,可以有任意数量的值或属性,而不仅仅是一个数字。考虑这个(未经测试)代码:

现在,您可以参考阵列的以下部分:

List<Map<String,String>> records = someCodeForReadingDataFromFile();
// read each line from the file ...            
String[] row = line.trim().split(",");            
String col2 = row[ ColumnEnum.COL1.index() ];    

你的代码可以工作。但是,如果您正在寻找“更好”的方法,您可能需要重新思考两点:

  • 列表的indexOf(object)方法不是那么快。成本O(n)。如果您维护一个
    映射
    ,并从colName获取索引,它应该比您当前的impl更快。除此之外,在java中,可以从枚举中获得不同类型的值。甚至可以让枚举实现接口

  • 您应该做一些异常处理。如果文件中的一行缺少一列(或多列),该怎么办。您当前的代码将抛出绑定外异常。然而,我希望这已经在你的真实代码中完成了


  • 你的代码可以工作。但是,如果您正在寻找“更好”的方法,您可能需要重新思考两点:

  • 列表的indexOf(object)方法不是那么快。成本O(n)。如果您维护一个
    映射
    ,并从colName获取索引,它应该比您当前的impl更快。除此之外,在java中,可以从枚举中获得不同类型的值。甚至可以让枚举实现接口

  • 您应该做一些异常处理。如果文件中的一行缺少一列(或多列),该怎么办。您当前的代码将抛出绑定外异常。然而,我希望这已经在你的真实代码中完成了


  • 是的,使用CSV解析器。像这样:是的,使用CSV解析器。像这样:只是出于好奇,既然您已经提到了它,
    enum
    s的性能与使用
    Map
    相比如何?谢谢@老实说,我不知道如何比较这两个。枚举是Columns类型的对象(在您的例子中),列可以有10000个对象/枚举。另一方面,map(例如hashmap)获取一个值的复杂度为O(1)。但是,后面有哈希函数,用于获取哈希。也会有碰撞。如何比较哈希表结构和对象。。。我不知道。只是出于好奇,既然你提到了它,
    enum
    s的性能与使用
    Map
    相比如何?谢谢@老实说,我不知道如何比较这两个。枚举是Columns类型的对象(在您的例子中),列可以有10000个对象/枚举。另一方面,map(例如hashmap)获取一个值的复杂度为O(1)。但是,后面有哈希函数,用于获取哈希。也会有碰撞。如何比较哈希表结构和对象。。。我不知道。