The Answer by qdoot seems correct. I'll add a few points:
- Use the more general
Map
as the type of your parameter. See another Question.
- Use NIO.2 in modern Java for working with files. See Wikipedia.
- The RFC 4180 standard specification for CSV, Common Format and MIME Type for Comma-Separated Values (CSV) Files, requires CRLF (Carriage Return, Linefeed) as the line terminator.
- Note that a
Map
such as ConcurrentHashMap
may iterate in any arbitrary order. If you care about order, use a NavigableMap
such as TreeMap
.
Core code:
try (
final Writer writer = Files.newBufferedWriter( path , StandardCharsets.UTF_8 ) ;
)
{
for ( Map.Entry < String, Integer > entry : nameToNumberMap.entrySet() )
{
String line = String.format( "%s,%d" , entry.getKey() , entry.getValue() );
writer.write( line.concat( CRLF ) );
}
}
catch ( IOException e )
{
System.out.println( "ERROR - Failed when opening or writing to file. " + Instant.now() + " Message # da8fc3ac-1f6b-4722-bbf9-a86f2acbb77f." );
throw new RuntimeException( e );
}
System.out.println( "INFO - Done writing CSV file. " + Instant.now() + " Message # fa26f37e-70b7-42e8-a8cf-bf72ad0b2da8." );
Full example app.
package work.basil.example.csv;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.Map;
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.demo();
}
private void demo ( )
{
Map < String, Integer > nameToNumberMap =
Map.of(
"Alice" , 1 ,
"Bob" , 2 ,
"Carol" , 3
);
Path path = Paths.get( "/Users/basil_dot_work" , "demo.csv" );
System.out.println( path.toAbsolutePath() );
this.writeCsv( nameToNumberMap , path );
}
private void writeCsv ( final Map < String, Integer > nameToNumberMap , final Path path )
{
// The RFC 4180 standard for CSV requires a CRLF (Carriage Return, Linefeed) as the line terminator. *Not* platform-specific, not Unix-style Linefeed.
final String CRLF = Character.toString( 13 ) + Character.toString( 10 );
// Open file.
try (
final Writer writer = Files.newBufferedWriter( path , StandardCharsets.UTF_8 ) ;
)
{
for ( Map.Entry < String, Integer > entry : nameToNumberMap.entrySet() )
{
String line = String.format( "%s,%d" , entry.getKey() , entry.getValue() );
writer.write( line.concat( CRLF ) );
}
}
catch ( IOException e )
{
System.out.println( "ERROR - Failed when opening or writing to file. " + Instant.now() + " Message # da8fc3ac-1f6b-4722-bbf9-a86f2acbb77f." );
throw new RuntimeException( e );
}
finally
{
System.out.println( "INFO - Done writing CSV file. " + Instant.now() + " Message # fa26f37e-70b7-42e8-a8cf-bf72ad0b2da8." );
}
}
}
When run.
/Users/some_user/demo.csv
INFO - Done writing CSV file. 2022-08-16T20:06:07.610196Z Message # fa26f37e-70b7-42e8-a8cf-bf72ad0b2da8.

Note to other readers: We used try-with-resources syntax to make sure the file is always closed gracefully, even when encountering exceptions. The code in the Question does the same. See The Java Tutorials by Oracle Corp.
This Question & Answer is for learning purposes. In real work, I would not generate CSV text. I would use one of the several good libraries available in the Java ecosystem for handling CSV text. Example: Apache Commons CSV.