Jua*_*esa 353 java string arraylist
我有一个ArrayList
我想完全输出为String.基本上我想按顺序输出它,使用toString
由制表符分隔的每个元素.有没有快速的方法来做到这一点?你可以循环它(或删除每个元素)并将它连接到一个字符串,但我认为这将是非常缓慢的.
Vit*_*nko 818
在Java 8或更高版本中:
String listString = String.join(", ", list);
Run Code Online (Sandbox Code Playgroud)
如果list
不是String类型,可以使用连接收集器:
String listString = list.stream().map(Object::toString)
.collect(Collectors.joining(", "));
Run Code Online (Sandbox Code Playgroud)
JJ *_*wax 382
如果您碰巧在Android上执行此操作,那么这个名为TextUtils的实用程序有一个很好的实用工具,它有一个.join(String delimiter, Iterable)
方法.
List<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
String joined = TextUtils.join(", ", list);
Run Code Online (Sandbox Code Playgroud)
显然没有多少在Android之外使用,但想通知我会把它添加到这个线程......
coo*_*ird 316
基本上,使用循环迭代ArrayList
是唯一的选择:
不要使用此代码,继续阅读本答案的底部,看看为什么不合适,以及应该使用哪些代码:
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
String listString = "";
for (String s : list)
{
listString += s + "\t";
}
System.out.println(listString);
Run Code Online (Sandbox Code Playgroud)
事实上,字符串连接将会很好,因为javac
编译器会将字符串连接优化为一系列append
操作StringBuilder
.以下是for
上述程序循环中字节码反汇编的一部分:
61: new #13; //class java/lang/StringBuilder
64: dup
65: invokespecial #14; //Method java/lang/StringBuilder."<init>":()V
68: aload_2
69: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
72: aload 4
74: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
77: ldc #16; //String \t
79: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
82: invokevirtual #17; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
Run Code Online (Sandbox Code Playgroud)
可以看出,编译器通过使用a来优化该循环StringBuilder
,因此性能不应该是一个大问题.
(好吧,第二眼,在StringBuilder
循环的每次迭代中都会实例化,因此它可能不是最有效的字节码.实例化和使用显式StringBuilder
可能会产生更好的性能.)
事实上,我认为任何类型的输出(无论是磁盘还是屏幕)都至少要比担心字符串连接的性能慢一个数量级.
编辑:正如评论中指出的,上面的编译器优化确实StringBuilder
在每次迭代时创建了一个新实例.(我之前已经注意到了.)
最优化的技术将是Paul Tomblin的响应,因为它只实例化循环StringBuilder
外的单个对象for
.
将以上代码重写为:
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
StringBuilder sb = new StringBuilder();
for (String s : list)
{
sb.append(s);
sb.append("\t");
}
System.out.println(sb.toString());
Run Code Online (Sandbox Code Playgroud)
只会StringBuilder
在循环外部实例化一次,并且只append
对循环内的方法进行两次调用,如此字节码(显示实例化StringBuilder
和循环)所示:
// Instantiation of the StringBuilder outside loop:
33: new #8; //class java/lang/StringBuilder
36: dup
37: invokespecial #9; //Method java/lang/StringBuilder."<init>":()V
40: astore_2
// [snip a few lines for initializing the loop]
// Loading the StringBuilder inside the loop, then append:
66: aload_2
67: aload 4
69: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
72: pop
73: aload_2
74: ldc #15; //String \t
76: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
79: pop
Run Code Online (Sandbox Code Playgroud)
因此,手优化确实应该更好地执行,因为for
循环内部更短并且不需要StringBuilder
在每次迭代时实例化.
Rav*_*lau 228
下载Jakarta Commons Lang并使用该方法
StringUtils.join(list)
StringUtils.join(list, ", ") // 2nd param is the separator.
Run Code Online (Sandbox Code Playgroud)
当然,您可以自己实现它,但是它们的代码经过了全面测试,可能是最好的实现.
我是Jakarta Commons库的忠实粉丝,我也认为它是Java标准库的一个很好的补充.
Jon*_*eet 139
这是一个非常古老的问题,但我想我不妨添加一个更现代的答案 - 使用Guava的Joiner
类:
String joined = Joiner.on("\t").join(list);
Run Code Online (Sandbox Code Playgroud)
She*_*g.W 82
将List更改为可读且有意义的String实际上是每个人都可能遇到的常见问题.
案例1.如果你的类路径中有apache的StringUtils(来自rogerdpack和Ravi Wallau):
import org.apache.commons.lang3.StringUtils;
String str = StringUtils.join(myList);
Run Code Online (Sandbox Code Playgroud)
案例2.如果您只想使用JDK(7)中的方法:
import java.util.Arrays;
String str = Arrays.toString(myList.toArray());
Run Code Online (Sandbox Code Playgroud)
永远不要自己制造轮子,不要使用循环来完成这个单线任务.
Ken*_*hih 59
如果您正在寻找一个快速的单行程序,从Java 5开始,您可以这样做:
myList.toString().replaceAll("\\[|\\]", "").replaceAll(", ","\t")
Run Code Online (Sandbox Code Playgroud)
此外,如果您的目的只是打印出内容并且不太关心"\ t",那么您可以这样做:
myList.toString()
Run Code Online (Sandbox Code Playgroud)
它返回一个字符串
[str1,str2,str3]
如果您有一个Array(而不是ArrayList),那么您可以像这样完成相同的操作:
Arrays.toString(myList).replaceAll("\\[|\\]", "").replaceAll(", ","\t")
Run Code Online (Sandbox Code Playgroud)
Pau*_*lin 38
循环遍历它并调用toString.没有一种神奇的方式,如果有的话,除了循环之外,你认为它会做什么呢?关于唯一的微优化将是使用StringBuilder而不是String,即使这不是一个巨大的胜利 - 连接字符串变成了StringBuilder的封面,但至少如果你这样写,你可以看到发生了什么.
StringBuilder out = new StringBuilder();
for (Object o : list)
{
out.append(o.toString());
out.append("\t");
}
return out.toString();
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 36
大多数Java项目通常都有可用的apache-commons.StringUtils.join()方法非常好,有几种口味可以满足几乎所有需求.
public static java.lang.String join(java.util.Collection collection,
char separator)
public static String join(Iterator iterator, String separator) {
// handle null, zero and one elements before building a buffer
Object first = iterator.next();
if (!iterator.hasNext()) {
return ObjectUtils.toString(first);
}
// two or more elements
StringBuffer buf =
new StringBuffer(256); // Java default is 16, probably too small
if (first != null) {
buf.append(first);
}
while (iterator.hasNext()) {
if (separator != null) {
buf.append(separator);
}
Object obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
return buf.toString();
}
Run Code Online (Sandbox Code Playgroud)
参数:
collection - 要连接在一起的值的集合,可以为null
separator - 要使用的分隔符
返回:连接的String,如果为null迭代器输入,则返回 null
自:2.3
keh*_*ers 16
Android有一个TextUtil类,你可以使用http://developer.android.com/reference/android/text/TextUtils.html
String implode = TextUtils.join("\t", list);
Run Code Online (Sandbox Code Playgroud)
Kha*_*M A 14
对于这个简单的用例,您可以使用逗号简单地连接字符串.如果您使用Java 8:
String csv = String.join("\t", yourArray);
Run Code Online (Sandbox Code Playgroud)
commons-lang有一个join()方法:
String csv = org.apache.commons.lang3.StringUtils.join(yourArray, "\t");
Run Code Online (Sandbox Code Playgroud)
aku*_*uhn 13
处理尾随分隔字符的一种优雅方法是使用Class Separator
StringBuilder buf = new StringBuilder();
Separator sep = new Separator("\t");
for (String each: list) buf.append(sep).append(each);
String s = buf.toString();
Run Code Online (Sandbox Code Playgroud)
Class Separator的toString方法返回分隔符,第一次调用除外.因此,我们打印列表而不尾随(或在这种情况下)前导分隔符.
ArrayList
class(Java Docs)扩展了AbstractList
类,它扩展了AbstractCollection
包含toString()
方法(Java Docs)的类.所以你只需写
listName.toString();
Run Code Online (Sandbox Code Playgroud)
Java开发人员已经找到了最有效的方法,并在一个包装精美且文档化的方法中为您提供了这些方法.只需调用该方法即可.
这是一种O(n)
算法(除非你做了一些多线程解决方案,你将列表分成多个子列表,但我不认为这是你要求的).
只需使用StringBuilder
如下:
StringBuilder sb = new StringBuilder();
for (Object obj : list) {
sb.append(obj.toString());
sb.append("\t");
}
String finalString = sb.toString();
Run Code Online (Sandbox Code Playgroud)
这StringBuilder
将比字符串连接快得多,因为您不会String
在每个连接上重新实例化对象.
在Java 8中很简单。请参阅示例以获取整数列表:
String result = Arrays.asList(1,2,3).stream().map(Object::toString).reduce((t, u) -> t + "\t" + u).orElse("");
Run Code Online (Sandbox Code Playgroud)
或多行版本(更易于阅读):
String result = Arrays.asList(1,2,3).stream()
.map(Object::toString)
.reduce((t, u) -> t + "\t" + u)
.orElse("");
Run Code Online (Sandbox Code Playgroud)
String result = Arrays.asList(1,2,3).stream()
.map(Object::toString)
.collect(Collectors.joining("\t"));
Run Code Online (Sandbox Code Playgroud)
如果你碰巧在Android上并且你还没有使用Jack(例如因为它仍然缺乏对Instant Run的支持),并且你想要更多地控制结果字符串的格式化(例如你想使用换行字符作为元素的分隔符,并碰巧使用/想要使用StreamSupport库(在Java 7或更早版本的编译器上使用流),你可以使用这样的东西(我把这个方法放在我的ListUtils类中):
public static <T> String asString(List<T> list) {
return StreamSupport.stream(list)
.map(Object::toString)
.collect(Collectors.joining("\n"));
}
Run Code Online (Sandbox Code Playgroud)
当然,确保在列表对象的类上实现toString().
一行:从 [12,0,1,78,12] 到 12 0 1 78 12
String srt= list.toString().replaceAll("\\[|\\]|,","");
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1007697 次 |
最近记录: |