当我在一个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中最好的方法是什么呢?
您可以编写一个连接风格的实用程序方法,它可以在java.util.Lists上工作
public static String join(List<String> list, String delim) {
StringBuilder sb = new StringBuilder();
String loopDelim = "";
for(String s : list) {
sb.append(loopDelim);
sb.append(s);
loopDelim = delim;
}
return sb.toString();
}
然后像这样使用它:
List<String> list = new ArrayList<String>();
if( condition ) list.add("elementName");
if( anotherCondition ) list.add("anotherElementName");
join(list, ",");
使用Dollar就像输入一样简单:
String joined = $(aCollection).join(",");
注意:它也适用于数组和其他数据类型
实现
在内部,它使用了一个非常巧妙的技巧:
@Override
public String join(String separator) {
Separator sep = new Separator(separator);
StringBuilder sb = new StringBuilder();
for (T item : iterable) {
sb.append(sep).append(item);
}
return sb.toString();
}
Separator类只在第一次调用时返回空String,然后返回分隔符:
class Separator {
private final String separator;
private boolean wasCalled;
public Separator(String separator) {
this.separator = separator;
this.wasCalled = false;
}
@Override
public String toString() {
if (!wasCalled) {
wasCalled = true;
return "";
} else {
return separator;
}
}
}