0

さまざまな列の型と値を持つ csv ファイルを解析することになっている Java コードを書いています。基本的なファイルは、ヘッダー/列行なしで、このようなもの (CSV) になります。ファイルの処理を簡単にするために、列名を使用して各セルのインデックス値にアクセスできるようにしたいと考えています。現時点では、CSV パーサーを使用したくありません

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

enum は C++ のように整数に変換されないため、列名の ArrayList を (順番に) 使用することを考えました。このようにして、次のようなことができます:

    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にかなり慣れていません-これを行うためのより良い/よりスマートな方法はありますか? ありがとう。

4

3 に答える 3

2

あなたのコードは機能します。ただし、「より良い」方法を探している場合は、再考する必要がある2つのポイントがあります。

  1. List の indexOf(object) メソッドはそれほど高速ではありません。コストは O(n) です。を維持しMap<columnNameString, indexNumber>、colName からインデックスを取得すると、現在の impl よりも高速になるはずです。それとは別に、Java では列挙型からさまざまな型の値を取得できます。列挙型にインターフェイスを実装させることもできます。

  2. 何らかの例外処理を行う必要があります。ファイルの 1 行に (または複数の) 列がない場合はどうでしょうか。現在のコードは OutOfbound 例外をスローします。ただし、これが実際のコードで既に行われていることを願っています。

于 2012-04-03T13:04:11.987 に答える
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 ライブラリまたはApache Commons CSV (非常に軽量!) をお勧めします。

于 2012-04-03T12:48:58.677 に答える
1

あなたの主張の 1 つが不正確です。「列挙型はC++のように整数に変換されない」と述べていますが、これは真実です。しかし、Java の Enum は実際にはそれよりも柔軟です! それらはオブジェクトであり、数値だけでなく、任意の数の値またはプロパティを持つことができます。この(テストされていない)コードを検討してください:

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() ];    
于 2012-04-03T12:53:54.247 に答える