2

Possible Duplicate:
Clearest way to comma-delimit a list (Java)?

I have a List<String> and I need to convert this list into the single line and insert delimiters between String elements of this List, except position before first element and after last element;

I have made a cycle like this:

StringBuffer sb = new StringBuffer();
for (String str : list) {
    sb.append(str).append(';');
}
if(sb.length() > 0)
    sb.deleteCharAt(sb.length() - 1);

I don't like delete last token sentence.

So, Which is more elegant way to do same?

Community
  • 1
  • 1
coms
  • 469
  • 15
  • 38

7 Answers7

11

Don't re-invent the wheel... the apache commons-lang library has the StringUtils.join() method, which does exactly what you want:

String s = StringUtils.join(list, ";"); // for example

Java 8 update:

In java 8, the String class has the join() method that does what you want:

String s = String.join(";", list);
Bohemian
  • 412,405
  • 93
  • 575
  • 722
5

Have a look at using Joiner in Google's Guava Libraries.

String delimitedString = Joiner.on(";").join(list);
Reimeus
  • 158,255
  • 15
  • 216
  • 276
1

Here is what I use, written in C# but you should be able to figure it out...

public static string DelimitList<T>(List<T> list, string delimiter)
{
    if (list == null || list.Count == 0 || delimiter == null)
    {
        return string.Empty;
    }

    StringBuilder delimitedList = new StringBuilder();
    for (int index = 0; index < list.Count - 1; index++)
    {
        delimitedList.Append(list[index]);
        delimitedList.Append(delimiter);
    }

    delimitedList.Append(list[list.Count - 1]);
    return delimitedList.ToString();
}
jtimperley
  • 2,494
  • 13
  • 11
1

Apache Commons Lang has a StringUtils class with a join method which allows you to do that:

StringUtils.join(list, ";");
João Silva
  • 89,303
  • 29
  • 152
  • 158
1

You have many recomendation and for third party libs.
My recommendation is, if you go for a for loop , if your code at that point does not need to be thread-safe, then use a StringBuilder instead. It is much faster than StringBuffer as it is unsynchronized

An example (just for different loop):

int len = list.size() - 1;
ListIterator<String> it = list.listIterator();  
StringBuilder sb = new StringBuilder();  
while(it.hasNext() && len-- > 0){  
   sb.append(it.next()).append(";");  
}  
if(it.hasNext()){  
   sb.append(it.next());  
}  
Cratylus
  • 52,998
  • 69
  • 209
  • 339
0

Well its not really more elegant, but you can check if its the first entry and otherwise add the delimiter upfront.

boolean isFirst = true;

StringBuffer sb = new StringBuffer();
for (String str : list) {
   if (!isFirst){
       sb.append(';');
   } 
   sb.append(str);
   isFirst = false;
}
Udo Held
  • 12,314
  • 11
  • 67
  • 93
  • Conversely, you can just do the first entry manually then use the loop to append the rest. – Aerowind Aug 14 '12 at 20:09
  • yes, but by just appending the delimiter every time, and deleting the last one, you're saving the "if" clause, which means the loop doesn't have a branch instruction in it, which will executed faster. – Matt Aug 14 '12 at 20:23
  • @Matt usually I wouldn't worry about the performance here. Its usually lost with IO and readabilty is more important(well this one looks nicer, but is just sligthly more readable). Checking the duplicate answer link, I do like the provided solution with adding the delimiter upfront evertime and exchanging it after the first round. – Udo Held Aug 14 '12 at 20:30
0

have a look at how ArrayList.toString() is written, that may help :

public String toString() {
    Iterator<E> i = iterator();
if (! i.hasNext())
    return "[]";

StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
    E e = i.next();
    sb.append(e == this ? "(this Collection)" : e);
    if (! i.hasNext())
    return sb.append(']').toString();
    sb.append(", ");
}
}

does this inspire you ?

mabroukb
  • 691
  • 4
  • 11