发布日期:2018-03-26
把Java的ArrayList转化成字符串的最好方法是什么?+ 查看更多
把Java的ArrayList转化成字符串的最好方法是什么?
+ 查看更多
发布日期:2018-03-23 17:02
分类:JAVA
浏览次数:113
我想把
ArrayList作为一个完成的字符串输出。本来我想要使用标号分别把每个元素用
toString
方法输出。有其他更快的方法来实现它吗?你可以循环遍历它(或者移除一个每个元素)然后把他们连结成字符串,但是我认为这个方法很慢。
回答
基本上,使用循环来迭代取得
ArrayList
是唯一的选择。
实际上,我认为任何一种输出(向磁盘或向显示器)都会比你担心的字符串连接的性能慢上一个数量级。
编辑:在评论中指出,编译器优化实际上会在每一个循环重复上创建一个新的
Paul Tomblin提出了一个最好的优化方法的使用,就是在
不要使用这个代码,继续阅读到本答案的底部你可以看到为什么它令人不满意,它应该被替换:
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编译器会优化字符串连接,总是把它作为一系列在
StringBuilder上的
append操作。这是从以上程序中的
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;
StringBuilder来优化此循环,所以性能应该不是一个大问题。 (好的,再认真看一下,
StringBuilder在循环的每次重复中都会被实例化,因此这可能不是最有效率的字节码。实例化并且使用一个明确的
StringBuilder可能会获得一个更好的性能。)
实际上,我认为任何一种输出(向磁盘或向显示器)都会比你担心的字符串连接的性能慢上一个数量级。
编辑:在评论中指出,编译器优化实际上会在每一个循环重复上创建一个新的
StringBuilder的实例(这一点我之前提到过)。
Paul Tomblin提出了一个最好的优化方法的使用,就是在
loop循环外面只初始化一个
StringBuilder的对象。
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."因此,手写的优化方法实际上性能会更好,因为for循环的内部更加简短以及不需要在每次循环迭代中都实例化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