当我在一个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。

其他回答

如果使用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中没有连接。

这样可能效果更好。

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();
}
//Note: if you have access to Java5+, 
//use StringBuilder in preference to StringBuffer.  
//All that has to be replaced is the class name.  
//StringBuffer will work in Java 1.4, though.

appendWithDelimiter( StringBuffer buffer, String addition, 
    String delimiter ) {
    if ( buffer.length() == 0) {
        buffer.append(addition);
    } else {
        buffer.append(delimiter);
        buffer.append(addition);
    }
}


StringBuffer parameterBuffer = new StringBuffer();
if ( condition ) { 
    appendWithDelimiter(parameterBuffer, "elementName", "," );
}
if ( anotherCondition ) {
    appendWithDelimiter(parameterBuffer, "anotherElementName", "," );
}

//Finally, to return a string representation, call toString() when returning.
return parameterBuffer.toString(); 

Java 8

stringCollection.stream().collect(Collectors.joining(", "));

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