当我在一个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中最好的方法是什么呢?


当前回答

如果您的代码不是线程化的,您应该使用StringBuilder,而不是使用字符串连接,如果是线程化的,则应该使用StringBuffer。

其他回答

基本上是这样的:

public static String appendWithDelimiter(String original, String addition, String delimiter) {

if (original.equals("")) {
    return addition;
} else {
    StringBuilder sb = new StringBuilder(original.length() + addition.length() + delimiter.length());
        sb.append(original);
        sb.append(delimiter);
        sb.append(addition);
        return sb.toString();
    }
}

还有一个最小值(如果你只是为了连接字符串而不想将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();
}

对于那些在Spring上下文中的人来说,他们的StringUtils类也很有用:

有很多有用的快捷方式,比如:

科尔collectionToCommaDelimitedString(收藏) 收集字符串(收集科尔,字符串) 弦(对象[]arr,弦delim)

还有很多其他的。

如果您还没有使用Java 8,并且已经在Spring上下文中,这将很有帮助。

对于Collection的支持,我更喜欢它而不是Apache Commons(尽管也很好),像这样更容易:

// Encoding Set<String> to String delimited 
String asString = org.springframework.util.StringUtils.collectionToDelimitedString(codes, ";");

// Decoding String delimited to Set
Set<String> collection = org.springframework.util.StringUtils.commaDelimitedListToSet(asString);

所以你可能会做一些事情来获得你想要的感觉:

1)扩展List类-并将join方法添加到其中。join方法将简单地完成连接和添加分隔符(可以是join方法的参数)的工作。

2)看起来java7将在Java中添加扩展方法——它允许你将一个特定的方法附加到一个类上:所以你可以编写join方法并将其作为扩展方法添加到List甚至Collection中。

解决方案1可能是目前唯一现实的解决方案,因为Java 7还没有出来:)但它应该工作得很好。

要使用这两种方法,你只需要像往常一样将所有项目添加到列表或集合中,然后调用新的自定义方法来“加入”它们。

public static String join(String[] strings, char del)
{
    StringBuffer sb = new StringBuffer();
    int len = strings.length;
    boolean appended = false;
    for (int i = 0; i < len; i++)
    {
        if (appended)
        {
            sb.append(del);
        }
        sb.append(""+strings[i]);
        appended = true;
    }
    return sb.toString();
}