[Java] 64 ネストしたArrayListのCSVファイル化 桁区切りカンマ対応

リストをCSVファイルにする際、リストの要素にカンマが含まれているとそこでも区切られてしまいリストの内容が正確に反映されません。

対策としてArrayListをフラット化すると同時に各要素をreplace関数でカンマ削除処理し、平滑化した配列から入れ子Listに組み直してCSVファイルにしました。平滑化配列から入れ子配列にするやり方がうまくいかなくて、どうにも野暮ったい方法を選択せざるを得ませんでした。

Pythonのように、CSVファイルにしてからpandasを使って簡単に加工したりすることができないのでかっちりとしたListを作らなければならず、かなり手間取りました。

CollectionUtils.chunkという自製メソッド(リストの要素を同じ数で入れ子にする)をネット情報を参考に作成し、なんとか形にできたような感じです。

Java8で追加されたStream API等がなかったら、Javaを第2言語から降格させていたかもしれません。ベテランユーザーの方々は相当苦労されていたと想像します。

今のところPythonと比較して開発速度は1/10から1/5位で、かなり遅いです。さらにスキルアップしてどこまで速くできるでしょう。

// raceリストを配列に変換   
        String[][] raceListConSorts_arrays = new String[raceListConSorts.size()][];
        int i = 0;
        for (ArrayList<String> ele:raceListConSorts) {
        	String print_list = String.format("raceListConSorts リスト%d個目 ",i);
        	System.out.println(print_list + ele);

        	String[] array = ele.toArray(new String[ele.size()]);
        	System.out.println("array " + Arrays.toString(array));

        	raceListConSorts_arrays[i] = array;
        	i = i + 1;
        }

        String[] arrayA = new String[21*raceListConSorts.size()];
        int i2 = 0;
        for (String[] ele:raceListConSorts_arrays) {
		  	System.out.println("arrays作成後array確認 " + Arrays.toString(ele));
		  	for (String ele2:ele) {
		  		ele2 = ele2.replace(",","");
		  		arrayA[i2] = ele2;
		  		i2 = i2 + 1;
		  	}
		  }

        System.out.println("arrayA " + Arrays.toString(arrayA));
        List<String> arrayA_list = Arrays.asList(arrayA);

        // 平滑化リストから入れ子リスト(各リスト要素数21)を作成
        List<List<String>>  listB = CollectionUtils.chunk(arrayA_list,21);
        System.out.println("listB " + listB);

        String[][] listB_array = new String[listB.size()][];
        int i3 = 0;
        for (List<String> ele:listB) {
            String[] array = ele.toArray(new String[ele.size()]);
            System.out.println("array " + i3 + " " + Arrays.toString(array));

            listB_array[i3] = array;
            i3 = i3 + 1;
        }

        List<String> list = Arrays.stream(listB_array)
        		.map(line -> String.join(",",line))
        		.collect(Collectors.toList());

        // csvファイル名を作成
        String[] filename_split = filename.split(Pattern.quote("."));
        System.out.println("filename_split " + filename_split);

        String csvname = filename_split[0] + ".csv";
        System.out.println("csvname " + csvname);

        try {
        	  Files.write(Paths.get(csvname), list, StandardOpenOption.CREATE);
       	}
        catch (IOException e) {
        	    e.printStackTrace();
    	}

[Java] 63 ネストしたArrayList→2次元配列→CSVファイル

ネストしたArrayListを2次元配列に変換し、CSVファイルにしました。確認のための出力はそのままにしています。

またしても文字列をドットにて分割するところでワナにかかりました。まだ2週間しかたっていないのに情けない。

こういったコードを書くとPythonのありがたさが身に染みます。文字列やリストを簡単に扱える自製ライブラリを作りたくなります。最初のfor文は結構手こずりました。appendを使えると大分違うのですが。出力時にtoStringメソッドを使うのも面倒です。

try文のcatchの直前に波カッコを書くことに違和感があるため、今のところ行が増えるのも構わず分けて書いています。審美的に難ありと思ったのですが、少数派でしょうね。

String[][] raceListConSorts_arrays = new String[raceListConSorts.size()][];
int i = 0;
for (ArrayList<String> ele:raceListConSorts) {
    String print_list = String.format("raceListConSorts リスト%d個目 ",i);
    System.out.println(print_list + ele);

    String[] array = ele.toArray(new String[ele.size()]);
    System.out.println("array " + Arrays.toString(array));

    raceListConSorts_arrays[i] = array;
    i = i + 1;
}

for (String[] ele:raceListConSorts_arrays) {
   	System.out.println("arrays作成後array確認 " + Arrays.toString(ele));
}

// 作成した2次元配列をCSV仕様に変換
List<String> list = Arrays.stream(raceListConSorts_arrays)
    .map(line -> String.join(",",line))
    .collect(Collectors.toList());

// HTMLファイル名からCSVファイル名を作成
String[] filename_split = filename.split(Pattern.quote("."));
System.out.println("filename_split " + filename_split);

String csvname = filename_split[0] + ".csv";
System.out.println("csvname " + csvname);

// CSVファイルを作成
try {
    Files.write(Paths.get(csvname), list, StandardOpenOption.CREATE);
}
catch (IOException e) {
    e.printStackTrace();
}