当我在一个Java应用程序中工作时,我最近需要组装一个以逗号分隔的值列表,以传递给另一个web服务,而不知道预先会有多少个元素。我能想到的最好的是这样的:

public String appendWithDelimiter( String original, String addition, String delimiter ) {
    if ( original.equals( "" ) ) {
        return addition;
    } else {
        return original + delimiter + addition;
    }
}

String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );

我意识到这不是特别有效,因为到处都在创建字符串,但我追求的是清晰而不是优化。

在Ruby中,我可以这样做,这感觉要优雅得多:

parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");

但是由于Java缺少join命令,我找不到任何等价的命令。

那么,在Java中最好的方法是什么呢?


当前回答

还有一个最小值(如果你只是为了连接字符串而不想将Apache Commons或Gauva包含到项目依赖项中)

/**
 *
 * @param delim : String that should be kept in between the parts
 * @param parts : parts that needs to be joined
 * @return  a String that's formed by joining the parts
 */
private static final String join(String delim, String... parts) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < parts.length - 1; i++) {
        builder.append(parts[i]).append(delim);
    }
    if(parts.length > 0){
        builder.append(parts[parts.length - 1]);
    }
    return builder.toString();
}

其他回答

谷歌的Guava库有com.google.common.base.Joiner类,它可以帮助解决这样的任务。

样品:

"My pets are: " + Joiner.on(", ").join(Arrays.asList("rabbit", "parrot", "dog")); 
// returns "My pets are: rabbit, parrot, dog"

Joiner.on(" AND ").join(Arrays.asList("field1=1" , "field2=2", "field3=3"));
// returns "field1=1 AND field2=2 AND field3=3"

Joiner.on(",").skipNulls().join(Arrays.asList("London", "Moscow", null, "New York", null, "Paris"));
// returns "London,Moscow,New York,Paris"

Joiner.on(", ").useForNull("Team held a draw").join(Arrays.asList("FC Barcelona", "FC Bayern", null, null, "Chelsea FC", "AC Milan"));
// returns "FC Barcelona, FC Bayern, Team held a draw, Team held a draw, Chelsea FC, AC Milan"

这是一篇关于Guava的字符串实用程序的文章。

如果使用Eclipse Collections,则可以使用makeString()或appendString()。

makeString()返回String表示形式,类似于toString()。

它有三种形式

makeString(开始,分隔符,结束) makeString(separator)默认开始和结束为空字符串 makeString()默认分隔符为","(逗号和空格)

代码示例:

MutableList<Integer> list = FastList.newListWith(1, 2, 3);
assertEquals("[1/2/3]", list.makeString("[", "/", "]"));
assertEquals("1/2/3", list.makeString("/"));
assertEquals("1, 2, 3", list.makeString());
assertEquals(list.toString(), list.makeString("[", ", ", "]"));

appendString()类似于makeString(),但它附加到Appendable(如StringBuilder),并且是空的。它有同样的三种形式,有一个额外的第一个参数,可追加的。

MutableList<Integer> list = FastList.newListWith(1, 2, 3);
Appendable appendable = new StringBuilder();
list.appendString(appendable, "[", "/", "]");
assertEquals("[1/2/3]", appendable.toString());

如果不能将集合转换为Eclipse Collections类型,只需使用相关的适配器对其进行调整。

List<Object> list = ...;
ListAdapter.adapt(list).makeString(",");

注意:我是Eclipse集合的提交者。

使用Java 5变量参数,所以你不需要将所有的字符串显式地填充到一个集合或数组中:

import junit.framework.Assert;
import org.junit.Test;

public class StringUtil
{
    public static String join(String delim, String... strings)
    {
        StringBuilder builder = new StringBuilder();

        if (strings != null)
        {
            for (String str : strings)
            {
                if (builder.length() > 0)
                {
                    builder.append(delim).append(" ");
                }
                builder.append(str);
            }
        }           
        return builder.toString();
    }
    @Test
    public void joinTest()
    {
        Assert.assertEquals("", StringUtil.join(",", null));
        Assert.assertEquals("", StringUtil.join(",", ""));
        Assert.assertEquals("", StringUtil.join(",", new String[0]));
        Assert.assertEquals("test", StringUtil.join(",", "test"));
        Assert.assertEquals("foo, bar", StringUtil.join(",", "foo", "bar"));
        Assert.assertEquals("foo, bar, x", StringUtil.join(",", "foo", "bar", "x"));
    }
}

不要使用join, delimiter或StringJoiner方法和类 在Android N和O版本下不工作。否则使用简单的代码逻辑 作为;

 List<String> tags= emp.getTags();
        String tagTxt="";
        for (String s : tags) {
            if (tagTxt.isEmpty()){
                tagTxt=s;
            }else
                tagTxt= tagTxt+", "+s;
        }  

我会使用谷歌集合。有一个很好的Join工具。 http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html

但如果我想自己写,

package util;

import java.util.ArrayList;
import java.util.Iterable;
import java.util.Collections;
import java.util.Iterator;

public class Utils {
    // accept a collection of objects, since all objects have toString()
    public static String join(String delimiter, Iterable<? extends Object> objs) {
        if (objs.isEmpty()) {
            return "";
        }
        Iterator<? extends Object> iter = objs.iterator();
        StringBuilder buffer = new StringBuilder();
        buffer.append(iter.next());
        while (iter.hasNext()) {
            buffer.append(delimiter).append(iter.next());
        }
        return buffer.toString();
    }

    // for convenience
    public static String join(String delimiter, Object... objs) {
        ArrayList<Object> list = new ArrayList<Object>();
        Collections.addAll(list, objs);
        return join(delimiter, list);
    }
}

我认为它更好地用于对象集合,因为现在你不必在加入它们之前将对象转换为字符串。