web-dev-qa-db-ja.com

Java-ハッシュマップをcsvファイルに書き込む

文字列キーと文字列値を持つハッシュマップがあります。多数のキーとそれぞれの値が含まれています。

例えば:

key | value
abc | aabbcc
def | ddeeff

このハッシュマップをcsvファイルに書き込み、csvファイルに次のような行が含まれるようにします。

abc,aabbcc
def,ddeeff

ここでは、supercsvライブラリを使用して次の例を試しました: http://javafascination.blogspot.com/2009/07/csv-write-using-Java.html 。ただし、この例では、csvファイルに追加する行ごとにハッシュマップを作成する必要があります。キーと値のペアが多数あるため、それぞれに1つの行のデータを含む複数のハッシュマップを作成する必要があります。このユースケースに使用できる、より最適化されたアプローチがあるかどうかを知りたいです。

前もって感謝します!

5
activelearner

あなたの質問はスーパーCSVを使用してこれを行う方法を尋ねているので、私は(プロジェクトのメンテナーとして)チャイムを鳴らしたいと思いました。

当初は、CsvBeanWriter"key", "value"の名前マッピング配列を使用してマップのエントリセットを反復処理できると思っていましたが、HashMapの内部実装では許可されていないため、これは機能しません。キー/値を取得するためのリフレクション。

したがって、唯一のオプションは、次のようにCsvListWriterを使用することです。少なくともこの方法では、CSVのエスケープについて心配する必要はありません(ここにある他のすべての例は、コンマで結合するだけです... aaarrggh!):

@Test
public void writeHashMapToCsv() throws Exception {
    Map<String, String> map = new HashMap<>();
    map.put("abc", "aabbcc");
    map.put("def", "ddeeff");

    StringWriter output = new StringWriter();
    try (ICsvListWriter listWriter = new CsvListWriter(output, 
         CsvPreference.STANDARD_PREFERENCE)){
        for (Map.Entry<String, String> entry : map.entrySet()){
            listWriter.write(entry.getKey(), entry.getValue());
        }
    }

    System.out.println(output);
}

出力:

abc,aabbcc
def,ddeeff
3
James Bassett

Jackson APIを使用すると、マップまたはマップのリストをCSVファイルに書き込むことができます。完全な例を参照してください ここ

 /**
 * @param listOfMap
 * @param writer
 * @throws IOException
 */
public static void csvWriter(List<HashMap<String, String>> listOfMap, Writer writer) throws IOException {
    CsvSchema schema = null;
    CsvSchema.Builder schemaBuilder = CsvSchema.builder();
    if (listOfMap != null && !listOfMap.isEmpty()) {
        for (String col : listOfMap.get(0).keySet()) {
            schemaBuilder.addColumn(col);
        }
        schema = schemaBuilder.build().withLineSeparator(System.lineSeparator()).withHeader();
    }
    CsvMapper mapper = new CsvMapper();
    mapper.writer(schema).writeValues(writer).writeAll(listOfMap);
    writer.flush();
}
5
Ajay

このような何かがトリックを行う必要があります:

String eol = System.getProperty("line.separator");

try (Writer writer = new FileWriter("somefile.csv")) {
  for (Map.Entry<String, String> entry : myHashMap.entrySet()) {
    writer.append(entry.getKey())
          .append(',')
          .append(entry.getValue())
          .append(eol);
  }
} catch (IOException ex) {
  ex.printStackTrace(System.err);
}
3
Sean Bright

ハッシュマップが1つしかない場合は、ほんの数行のコードです。このようなもの:

Map<String,String> myMap = new HashMap<>();

myMap.put("foo", "bar");
myMap.put("baz", "foobar");

StringBuilder builder = new StringBuilder();
for (Map.Entry<String, String> kvp : myMap.entrySet()) {
    builder.append(kvp.getKey());
    builder.append(",");
    builder.append(kvp.getValue());
    builder.append("\r\n");
}

String content = builder.toString().trim();
System.out.println(content);
//use your prefered method to write content to a file - for example Apache FileUtils.writeStringToFile(...) instead of syso.    

結果は

foo,bar
baz,foobar
0
dognose

私のJavaは少し制限されていますが、HashMapをループして、各エントリを文字列に追加することはできませんか?

// m = your HashMap

StringBuilder builder = new StringBuilder();
for(Entry<String, String> e : m.entrySet()) 
{
    String key = e.getKey();
    String value = e.getValue();

    builder.append(key);
    builder.append(',');
    builder.append(value);
    builder.append(System.getProperty("line.separator"));
}

string result = builder.toString();
0
James