LoginSignup
0
0

More than 5 years have passed since last update.

CSVを値をオブジェクトに設定するときのプラクティス

Last updated at Posted at 2018-12-12

CSVを読み込んで、その値を1レコードに1オブジェクトに保持させたいときがあります。
たとえば、

tokyo.csv
千代田区,ちよだく,Chiyodaku
中央区,ちゅうおうく,Chuoku
港区,みなとく,Minatoku
新宿区,しんじゅくく,Shinjukuku
文京区,ぶんきょうく,Bunkyoku
台東区,たいとうく,Taitoku
墨田区,すみだく,Sumidaku
(以下略)

を1行ずつ処理しようとすると、こんな感じになるかと思います。

TokyoWard.java

public class TokyoWard {

    private String kanji;

    private String kana;

    private String roman;

    public TokyoWard(String line) {
        String[] columns = line.split(",", -1);
        this.kanji = columns[0];
        this.kana = columns[1];
        this.roman = columns[2];
    }
}
Main.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Main {

    public static void main(String[] args) throws IOException {
        for (String line : Files.readAllLines(Paths.get("../tokyo.csv"))) {
            TokyoWard ward = new TokyoWard(line);
        }
    }
}

TokyoWardのコンストラクタで、インデックスを指定してカラムを取り出しています。
しかしこれだと、CSVのカラムの順序が入れ替わったときに、インデックスを修正する必要があります。

tokyo.csv
千代田区,ちよだく,Chiyodaku
中央区,ちゅうおうく,Chuoku

tokyo.csv
ちよだく,Chiyodaku,千代田区
ちゅうおうく,Chuoku,中央区

に変わると、プロパティへの設定箇所も、以下のように変わります。

TokyoWard.java
    public TokyoWard(String line) {
        String[] columns = line.split(",", -1);
        // this.kanji = columns[0];
        // this.kana = columns[1];
        // this.roman = columns[2];

        this.kanji = columns[2];
        this.kana = columns[0];
        this.roman = columns[1];
    }

3カラムくらいだと配列のインデックス修正もかわいいもんですが、何十とカラムのあるCSVだと割と手間です。
さらに実際には、可読性を考慮して、コードの順序も変更します。
CSVのカラムの順序と一致していたほうがわかりやすいですからね…

TokyoWard.java
    public TokyoWard(String line) {
        String[] columns = line.split(",", -1);
        // this.kanji = columns[0];
        // this.kana = columns[1];
        // this.roman = columns[2];

        // this.kanji = columns[2];
        // this.kana = columns[0];
        // this.roman = columns[1];

        this.kana = columns[0];
        this.roman = columns[1];
        this.kanji = columns[2];
    }

そこで、どうせCSVのカラムの順序に合わせたコーディングをするのなら、CSVのカラムの順序とプロパティの設定順序を一致させてしまえばいいのでは?と考えたのがこちら。

TokyoWard.java
    public TokyoWard(String line) {
        String[] columns = line.split(",", -1);
        int index = 0;
        this.kana = columns[index++];
        this.roman = columns[index++];
        this.kanji = columns[index++];
    }

こうすることで、

  • マジックナンバーを最小限に抑えられる(int index = 0のみ)
  • CSVのカラムの順序が変わっても、その順序変更に合わせてコードの順序を変えるだけで良い(インデックスを一つ一つ書き換える必要がない)

というようなメリットがあります。
外部ファイルとコードが密結合チックになっちゃうのは気になりますが…。
もっと良い方法があるのかなあ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0