Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 299048

Preferred Idiom for Joining a Collection of Strings in Java

Given a Collection of Strings, how would you join them in plain Java, without using an external Library?

Given these variables:

Collection<String> data = Arrays.asList("Snap", "Crackle", "Pop");
String separator = ", ";
String joined; // let's create this, shall we?

This is how I'd do it in Guava:

joined = Joiner.on(separator).join(data);

And in Apache Commons / Lang:

joined = StringUtils.join(data, separator);

But in plain Java, is there really no better way than this?

StringBuilder sb = new StringBuilder();
for(String item : data){
    if(sb.length()>0)sb.append(separator);
    sb.append(item);
}
joined = sb.toString();

Upvotes: 22

Views: 8258

Answers (7)

Matthias Braun
Matthias Braun

Reputation: 34373

Collectors can join Streams which is very useful if you want to filter or map your data.

String joined = Stream.of("Snap", "Crackle", "Pop")
        .map(String::toUpperCase)
        .collect(Collectors.joining(", "));

To get a Stream from a Collection, call stream() on it:

Arrays.asList("Snap", "Crackle", "Pop").stream()

Upvotes: 1

aioobe
aioobe

Reputation: 421090

Java 8+

joined =String.join(separator, data);

Java 7 and below

StringBuilder sb = new StringBuilder();
boolean first = true;
for(String item : data){
    if(!first || (first = false)) sb.append(separator);
    sb.append(item);
}
joined = sb.toString();

Upvotes: 8

Jules
Jules

Reputation: 15199

In Java 8:

String.join (separator, data)

Upvotes: 5

ColinD
ColinD

Reputation: 110054

I'd say the best way of doing this (if by best you don't mean "most concise") without using Guava is using the technique Guava uses internally, which for your example would look something like this:

Iterator<String> iter = data.iterator();
StringBuilder sb = new StringBuilder();
if (iter.hasNext()) {
  sb.append(iter.next());
  while (iter.hasNext()) {
    sb.append(separator).append(iter.next());
  }
}
String joined = sb.toString();

This doesn't have to do a boolean check while iterating and doesn't have to do any postprocessing of the string.

Upvotes: 15

Dead Programmer
Dead Programmer

Reputation: 12585

May be instead of calling sb.length() again and again in a loop, i have slightly modified.

StringBuilder sb = new StringBuilder();
String separator = "";
for(String item : data){
    sb.append(separator);
    separator=",";
    sb.append(item);
}
joined = sb.toString();

Upvotes: 10

卢声远 Shengyuan Lu
卢声远 Shengyuan Lu

Reputation: 32014

Different intentions:

For third-part tools, such as Guava's Joiner, which is not fast, but very flexible. There are many option methods to customize join behavior, such as skipNulls().

Plain Java is fast, but it needs you write some lines of codes by yourself.

Upvotes: 1

Nicolas
Nicolas

Reputation: 24769

Your proposition is a possible solution, another common one is:

for (String item: data) {
    sb.append(item)
    sb.append(separator);
}
String joined = sb.substring(0, sb.length() - separator.length())

Upvotes: 0

Related Questions