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


当前回答

对于那些在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);

其他回答

使用基于java.lang.StringBuilder的方法!(“一个可变的字符序列。”)

就像你提到的,所有那些字符串连接都在创建字符串。StringBuilder不会这样做。

为什么用StringBuilder代替StringBuffer?从StringBuilder javadoc:

在可能的情况下,建议优先使用这个类而不是StringBuffer,因为在大多数实现中它会更快。

使用StringBuilder和类Separator

StringBuilder buf = new StringBuilder();
Separator sep = new Separator(", ");
for (String each : list) {
    buf.append(sep).append(each);
}

分隔符包装分隔符。分隔符由Separator的toString方法返回,除非第一次调用返回空字符串!

类分隔符的源代码

public class Separator {

    private boolean skipFirst;
    private final String value;

    public Separator() {
        this(", ");
    }

    public Separator(String value) {
        this.value = value;
        this.skipFirst = true;
    }

    public void reset() {
        skipFirst = true;
    }

    public String toString() {
        String sep = skipFirst ? "" : value;
        skipFirst = false;
        return sep;
    }

}

为此,您可以使用Java的StringBuilder类型。还有StringBuffer,但它包含额外的线程安全逻辑,这通常是不必要的。

为什么不编写自己的join()方法呢?它将接受String和分隔符String的参数集合。在方法中遍历集合并在StringBuffer中构建结果。

您可以泛化它,但正如您所说,Java中没有连接。

这样可能效果更好。

public static String join(Iterable<? extends CharSequence> s, String delimiter) {
    Iterator<? extends CharSequence> iter = s.iterator();
    if (!iter.hasNext()) return "";
    StringBuilder buffer = new StringBuilder(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}