在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", "," );
Run Code Online (Sandbox Code Playgroud)
我意识到这不是特别有效,因为在整个地方都会创建字符串,但我的目的是为了清晰而不是优化.
在Ruby中,我可以做这样的事情,感觉更优雅:
parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");
Run Code Online (Sandbox Code Playgroud)
但由于Java缺少连接命令,我无法弄清楚任何等价物.
那么,在Java中执行此操作的最佳方法是什么?
小智 521
Apache的commons lang是你的朋友 - 它提供了一个非常类似于你在Ruby中引用的连接方法:
StringUtils.join(java.lang.Iterable,char)
Java 8通过StringJoiner和提供开箱即用的加入String.join().下面的代码段显示了如何使用它们:
StringJoiner joiner = new StringJoiner(",");
joiner.add("01").add("02").add("03");
String joinedString = joiner.toString(); // "01,02,03"
Run Code Online (Sandbox Code Playgroud)
String.join(CharSequence delimiter, CharSequence... elements))
String joinedString = String.join(" - ", "04", "05", "06"); // "04 - 05 - 06"
Run Code Online (Sandbox Code Playgroud)
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
List<String> strings = new LinkedList<>();
strings.add("Java");strings.add("is");
strings.add("cool");
String message = String.join(" ", strings);
//message returned is: "Java is cool"
Run Code Online (Sandbox Code Playgroud)
小智 52
您可以编写一个适用于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();
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
List<String> list = new ArrayList<String>();
if( condition ) list.add("elementName");
if( anotherCondition ) list.add("anotherElementName");
join(list, ",");
Run Code Online (Sandbox Code Playgroud)
Kev*_*vin 47
在Android的情况下,来自commons的StringUtils类不可用,所以为此我使用了
android.text.TextUtils.join(CharSequence delimiter, Iterable tokens)
Run Code Online (Sandbox Code Playgroud)
http://developer.android.com/reference/android/text/TextUtils.html
Ale*_*x K 31
在谷歌的番石榴库具有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"
Run Code Online (Sandbox Code Playgroud)
mic*_*cha 25
在Java 8中,您可以使用String.join():
List<String> list = Arrays.asList("foo", "bar", "baz");
String joined = String.join(" and ", list); // "foo and bar and baz"
Run Code Online (Sandbox Code Playgroud)
还要看一下Stream API示例的答案.
Vin*_*vic 20
您可以对它进行概括,但正如您所说,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();
}
Run Code Online (Sandbox Code Playgroud)
Stu*_*son 15
使用基于的方法java.lang.StringBuilder!("一个可变的字符序列.")
就像你提到的那样,所有这些字符串连接都在创建字符串. StringBuilder不会这样做.
为什么StringBuilder而不是StringBuffer?来自StringBuilderjavadoc:
在可能的情况下,建议首先使用此类优先于StringBuffer,因为在大多数实现中它会更快.
gla*_*tor 15
在Java 8中你可以这样做:
list.stream().map(Object::toString)
.collect(Collectors.joining(delimiter));
Run Code Online (Sandbox Code Playgroud)
如果list有空值,你可以使用:
list.stream().map(String::valueOf)
.collect(Collectors.joining(delimiter))
Run Code Online (Sandbox Code Playgroud)
Eri*_*and 10
我会使用Google Collections.有一个很好的加入设施.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为它对象集合更好用,因为现在你不必在加入它们之前将对象转换为字符串.
stringCollection.stream().collect(Collectors.joining(", "));
Run Code Online (Sandbox Code Playgroud)
小智 5
Java 8 原生类型
List<Integer> example;
example.add(1);
example.add(2);
example.add(3);
...
example.stream().collect(Collectors.joining(","));
Run Code Online (Sandbox Code Playgroud)
Java 8 自定义对象:
List<Person> person;
...
person.stream().map(Person::getAge).collect(Collectors.joining(","));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
251978 次 |
| 最近记录: |