当前位置:  开发笔记 > 编程语言 > 正文

将ArrayList转换为字符串的最佳方法

如何解决《将ArrayList转换为字符串的最佳方法》经验,为你挑选了16个好方法。

我有一个ArrayList我想完全输出为String.基本上我想按顺序输出它,使用toString由制表符分隔的每个元素.有没有快速的方法来做到这一点?你可以循环它(或删除每个元素)并将它连接到一个字符串,但我认为这将是非常缓慢的.



1> Vitalii Fedo..:

在Java 8或更高版本中:

String listString = String.join(", ", list);

如果list不是String类型,可以使用连接收集器:

String listString = list.stream().map(Object::toString)
                        .collect(Collectors.joining(", "));


我不敢相信,直到Java 8才能添加它.
这个答案应该多投票!没有黑客,没有库和没有循环.
这不适用于OP所说的.String.join作为第二个参数Iterable <?扩展CharSequence>.因此,如果你想要显示一个List ,它就有效,但是如果你有List ,它将*不会*按照OP的要求调用toString()
为什么这不是第一个(并且被接受的)答案..我总是向下滚动,直到我知道它在那里..优雅和简洁

2> JJ Geewax..:

如果您碰巧在Android上执行此操作,那么这个名为TextUtils的实用程序有一个很好的实用工具,它有一个.join(String delimiter, Iterable)方法.

List list = new ArrayList();
list.add("Item 1");
list.add("Item 2");
String joined = TextUtils.join(", ", list);

显然没有多少在Android之外使用,但想通知我会把它添加到这个线程......


`org.apache.lang3.StringUtils`几乎一样,所以你的答案在Android之外绝对有用了:)

3> coobird..:

基本上,使用循环迭代ArrayList是唯一的选择:

不要使用此代码,继续阅读本答案的底部,看看为什么不合适,以及应该使用哪些代码:

ArrayList list = new ArrayList();
list.add("one");
list.add("two");
list.add("three");

String listString = "";

for (String s : list)
{
    listString += s + "\t";
}

System.out.println(listString);

事实上,字符串连接将会很好,因为javac编译器会将字符串连接优化为一系列append操作StringBuilder.以下是for上述程序循环中字节码反汇编的一部分:

   61:  new #13; //class java/lang/StringBuilder
   64:  dup
   65:  invokespecial   #14; //Method java/lang/StringBuilder."":()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;

可以看出,编译器通过使用a来优化该循环StringBuilder,因此性能不应该是一个大问题.

(好吧,第二眼,在StringBuilder循环的每次迭代中都会实例化,因此它可能不是最有效的字节码.实例化和使用显式StringBuilder可能会产生更好的性能.)

事实上,我认为任何类型的输出(无论是磁盘还是屏幕)都至少要比担心字符串连接的性能慢一个数量级.

编辑:正如评论中指出的,上面的编译器优化确实StringBuilder在每次迭代时创建了一个新实例.(我之前已经注意到了.)

最优化的技术将是Paul Tomblin的响应,因为它只实例化循环StringBuilder外的单个对象for.

将以上代码重写为:

ArrayList list = new ArrayList();
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());

只会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."":()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

因此,手优化确实应该更好地执行,因为for循环内部更短并且不需要StringBuilder在每次迭代时实例化.


此解决方案在字符串的末尾添加了额外的"\ t",这通常是不期望的,尤其是当您要创建逗号分隔列表或类似内容时.我认为使用Apache Commons或Guava发布的其他解决方案都非常出色.
出于性能原因,请考虑使用StringBuilder类而不是仅附加字符串.
编译器将优化字符串连接,但每次执行循环时都将创建一个新的StringBuilder对象.
-1表示使用+ =,在这种情况下它是性能杀手.始终使用StringBuilder重复追加到字符串.
这不是最佳答案。在下面的Vitalii中查找Java,在Geewax中查找Android。

4> Ravi Wallau..:

下载Jakarta Commons Lang并使用该方法

 StringUtils.join(list)

 StringUtils.join(list, ", ") // 2nd param is the separator.

当然,您可以自己实现它,但是它们的代码经过了全面测试,可能是最好的实现.

我是Jakarta Commons库的忠实粉丝,我也认为它是Java标准库的一个很好的补充.


不幸的是,SO的居民更喜欢重新发明轮子.
也在Apache Commons Lang中.用法看起来像`StringUtils.join(list.toArray(),"\ t")`
这个特殊的轮子几乎不值得额外依赖.
@SevaAlekseyev我认为这是值得商榷的.如果您立即添加此依赖项,您将更多地使用它的类.您将使用StringUtils.isNotEmpty而不是使用"if string!= null && string.trim()!=""...您将使用ObjectUtils.equals(),这样您就不必在任何地方检查null.但是如果你等待使用这些库的一个依赖项,你可能永远不会真正使用它们.
它最好不会在最后添加额外的标签!
另外,使用Apache Commons 3,没有必要将列表转换为数组.只需使用:`StringUtils.join(list,"\ t")`.

5> Jon Skeet..:

这是一个非常古老的问题,但我想我不妨添加一个更现代的答案 - 使用Guava的Joiner类:

String joined = Joiner.on("\t").join(list);


这是我最喜欢的解决方案.: - >番石榴+1.

6> Sheng.W..:

List更改为可读且有意义的String实际上是每个人都可能遇到的常见问题.

案例1.如果你的类路径中有apache的StringUtils(来自rogerdpack和Ravi Wallau):

import org.apache.commons.lang3.StringUtils;
String str = StringUtils.join(myList);

案例2.如果您只想使用JDK(7)中的方法:

import java.util.Arrays;
String str = Arrays.toString(myList.toArray()); 

永远不要自己制造轮子,不要使用循环来完成这个单线任务.


`Arrays.toString(myList.toArray())` - 最简单,最直接的解决方案

7> Ken Shih..:

如果您正在寻找一个快速的单行程序,从Java 5开始,您可以这样做:

myList.toString().replaceAll("\\[|\\]", "").replaceAll(", ","\t")

此外,如果您的目的只是打印出内容并且不太关心"\ t",那么您可以这样做:

myList.toString()

它返回一个字符串

[str1,str2,str3]

如果您有一个Array(而不是ArrayList),那么您可以像这样完成相同的操作:

 Arrays.toString(myList).replaceAll("\\[|\\]", "").replaceAll(", ","\t")


我认为这实际上比上面发布的方法更有效.这样的耻辱就显示在底部.它可能不优雅,但我坚信你的解决方案运行O(n)而其他理论上运行在O(n ^ 2)(因为Java字符串是不可变的,你基本上在每次合并时创建一个新的字符串,它变得更糟,因为结果字符串变大)

8> Paul Tomblin..:

循环遍历它并调用toString.没有一种神奇的方式,如果有的话,除了循环之外,你认为它会做什么呢?关于唯一的微优化将是使用StringBuilder而不是String,即使这不是一个巨大的胜利 - 连接字符串变成了StringBuilder的封面,但至少如果你这样写,你可以看到发生了什么.

StringBuilder out = new StringBuilder();
for (Object o : list)
{
  out.append(o.toString());
  out.append("\t");
}
return out.toString();


对于大型阵列,这绝对不是微优化.对于每个字符串连接,单独完成使用StringBuilder的自动转换,这在循环的情况下没有帮助.如果在一个表达式中连接大量元素,则可以.

9> Brian..:

大多数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();
}

参数:

collection - 要连接在一起的值的集合,可以为null

separator - 要使用的分隔符

返回:连接的String,如果为null迭代器输入,则返回 null

自:2.3


这非常好,因为`join(...)`方法有数组和集合的变体.

10> kehers..:

Android有一个TextUtil类,你可以使用http://developer.android.com/reference/android/text/TextUtils.html

String implode = TextUtils.join("\t", list);



11> Khader M A..:

对于这个简单的用例,您可以使用逗号简单地连接字符串.如果您使用Java 8:

String csv = String.join("\t", yourArray);

commons-lang有一个join()方法:

String csv = org.apache.commons.lang3.StringUtils.join(yourArray, "\t");



12> akuhn..:

处理尾随分隔字符的一种优雅方法是使用Class Separator

StringBuilder buf = new StringBuilder();
Separator sep = new Separator("\t");
for (String each: list) buf.append(sep).append(each);
String s = buf.toString();

Class Separator的toString方法返回分隔符,第一次调用除外.因此,我们打印列表而不尾随(或在这种情况下)前导分隔符.



13> golddove..:

ArrayListclass(Java Docs)扩展了AbstractList类,它扩展了AbstractCollection包含toString()方法(Java Docs)的类.所以你只需写

listName.toString();

Java开发人员已经找到了最有效的方法,并在一个包装精美且文档化的方法中为您提供了这些方法.只需调用该方法即可.



14> Mike C...:

这是一种O(n)算法(除非你做了一些多线程解决方案,你将列表分成多个子列表,但我不认为这是你要求的).

只需使用StringBuilder如下:

StringBuilder sb = new StringBuilder();

for (Object obj : list) {
  sb.append(obj.toString());
  sb.append("\t");
}

String finalString = sb.toString();

StringBuilder将比字符串连接快得多,因为您不会String在每个连接上重新实例化对象.



15> amra..:

在Java 8中很简单。请参阅示例以获取整数列表:

String result = Arrays.asList(1,2,3).stream().map(Object::toString).reduce((t, u) -> t + "\t" + u).orElse("");

或多行版本(更易于阅读):

String result = Arrays.asList(1,2,3).stream()
    .map(Object::toString)
    .reduce((t, u) -> t + "\t" + u)
    .orElse("");
更新-较短的版本
String result = Arrays.asList(1,2,3).stream()
                .map(Object::toString)
                .collect(Collectors.joining("\t"));


在Java 8中:String.join(“ \ t”,array)

16> Javad Sadeqz..:

如果你碰巧在Android上并且你还没有使用Jack(例如因为它仍然缺乏对Instant Run的支持),并且你想要更多地控制结果字符串的格式化(例如你想使用换行字符作为元素的分隔符,并碰巧使用/想要使用StreamSupport库(在Java 7或更早版本的编译器上使用流),你可以使用这样的东西(我把这个方法放在我的ListUtils类中):

public static  String asString(List list) {
    return StreamSupport.stream(list)
            .map(Object::toString)
            .collect(Collectors.joining("\n"));
}

当然,确保在列表对象的类上实现toString().

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有