Creating CSV from Strings in Java
#javaEarlier in Java 7, you needed a StringBuilder to create a CSV from list. From Java 8 onwards, there are multiple ways to achieve this depending on the task in hand.
1. Using the String.join method
The String class has a join method that take a delimiter.
List<String> tokens = Arrays.asList("one", "two", "three");
String joined = String.join(",", tokens);
System.out.println(joined);
// --output --
// one,two,three
2. Using the StringJoiner
Another similar way to achieve this is using the StringJoiner class.
List<String> tokens = Arrays.asList("one", "two", "three");
StringJoiner joiner = new StringJoiner(",");
for (String item : tokens) {
joiner.add(item);
}
System.out.println(joiner.toString());
// -- output --
// one,two,three
We can add prefix and suffix with StringJoiner, which can prove helpful in case we want to surround the output with something.
List<String> tokens = Arrays.asList("one", "two", "three");
StringJoiner joiner = new StringJoiner(",", "[", "]");
for (String item : tokens) {
joiner.add(item);
}
System.out.println(joiner.toString());
// -- output --
// [one,two,three]
A more practical use case of this would be in case of creating a multiline CSV where you want the header row as well:
List<String> tokens = Arrays.asList("one", "two", "three");
String header = "numbers";
StringJoiner joiner = new StringJoiner("\n", header + "\n", "");
for (String item : tokens) {
joiner.add(item);
}
System.out.println(joiner.toString());
-- output --
// numbers
// one
// two
// three
3. Using Java Stream
Strings can be combined using Collectors. There is a joining collector in Java using which you can join items of a list or collection.
System.out.println(tokens.stream().collect(Collectors.joining(",")));
This gives the same output as above.
4. Using Streams and Reducers
Creating a CSV out of multiple strings is nothing but creating a single string out of many. This can be achieved using reducers as well:
Optional<String> f = tokens.stream().collect(Collectors.reducing(new BinaryOperator<String>() {
@Override
public String apply(String t, String u) {
return t + "," + u;
}
}));
System.out.println(f.get());
// -- output --
// one,two,three
This can also be rewritten in a single line as follows:
Optional<String> f = tokens.stream().collect(Collectors.reducing((t, u) -> t + "," + u));
System.out.println(f.get());
// -- output --
// one,two,three
These are just helper methods and don’t have any performance improvements over the good old StringBuilder method we used to use before Java 8.