简体   繁体   中英

What's the most elegant way to concatenate a list of values with delimiter in Java?

I have never found a neat(er) way of doing the following.

Say I have a list/array of strings.

abc
def
ghi
jkl

And I want to concatenate them into a single string delimited by a comma as follows:

abc,def,ghi,jkl

In Java, if I write something like this (pardon the syntax),

String[] list = new String[] {"abc","def","ghi","jkl"};
String str = null;
for (String s : list)
{
   str = str + s + "," ;
}

System.out.println(str);

I'll get

abc,def,ghi,jkl,  //Notice the comma in the end

So I have to rewrite the above for loop as follows

...
for (int i = 0; i < list.length; i++)
{
   str = str + list[i];
   if (i != list.length - 1)
   {
     str = str + ",";
   }
}
...

Can this be done in a more elegant way in Java?

I would certainly use a StringBuilder/Buffer for efficiency, but I wanted to illustrate the case in point without being too verbose. By elegant, I mean a solution that avoids the ugly(?) if check inside the loop.

Using Guava's (formerly google-collections) joiner class :

Joiner.on(",").join(list)

Done.

Here is my version: Java Tricks: Fastest Way to Collecting Objects in a String

StringBuilder buffer = new StringBuilder ();
String delim = "";
for (Object o: list)
{
    buffer.append (delim);
    delim = ", "; // Avoid if(); assignment is very fast!
    buffer.append (o);
}
buffer.toString ();

As an additional bonus: If your code in the loop is more complex, then this approach will produce a correct results without complex if() s.

Also note that with modern CPUs, the assignment will happen only in the cache (or probably only in a register).

Conclusion: While this code looks odd at first glance, it has many advantages.

StringBuilder builder = new StringBuilder();
for (String st: list) {
    builder.append(st).append(',');
}
builder.deleteCharAt(builder.length());
String result = builder.toString();

Do not use '+' for string contacenations. It`s slow.

Look here:

http://snippets.dzone.com/posts/show/91

for a full discussion of this topic.

I'd bet that there are several classes named "StringUtil", "StringsUtil", "Strings" or anything along those lines on the classpath of any medium sized Java project. Most likely, any of them will provide a join function. Here are some examples I've found in my project:

org.apache.commons.lang.StringUtils.join(...)
org.apache.wicket.util.string.Wicket.join(...)
org.compass.core.util.StringUtils.arrayToDelimitedString(...)

As you might want to get rid of some external dependencies in the future, you may want to to something like this:

public static final MyStringUtils {
    private MyStringUtils() {}

    public static String join(Object[] list, String delim) {
        return org.apache.commons.lang.StringUtils.join(list, delim);
    }
}

Now that's what I call "elegant" ;)

check if this is useful:

List<Integer> numbers=new ArrayList<Integer>();
    numbers.add(1);
    numbers.add(2);
    numbers.add(3);
    numbers.add(4);
    numbers.add(5);
    numbers.add(6);
    String str = " ";
    for(Integer s:numbers){
    str=str+s+" , ";
    }
    System.out.println(str.substring(0,str.length()-2));

I would use a StringBuffer to implement this feature. String is immutable so everytime you concat two String s, a new object is created.

More efficient is the use of StringBuffer :

String[] list = new String[] {"abc","def","ghi","jkl"};
StringBuffer str = new StringBuffer();
for (String s : list) {
   str.append(s);
   str.append(",");
}
str.deleteCharAt(str.length());
System.out.println(str); //automatically invokes StringBuffer.toString();
for (int i = 0; i < list.length-1; i++) {
    str = str + list[i];
    str = str + ",";    
}
str = str + list[list.length-1] 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM