StringBuilder的append、StringBuffer的append和String str = "a"+"b"的区别?
大家都知道String+String会开销额外的系统资源,粗略的原因是String是不可变类,每一步操作都会返回新的String变量,占用空间及时间。
其实我的理解不是这样的,我们来看看String+的底层实现。
测试案例
public static void main(String[] args) {
String a = "a";
StringBuilder b = new StringBuilder("b");
StringBuffer c = new StringBuffer("c");
long star = System.currentTimeMillis();
for(int i=0;i<200000;i++){
a+="a";
}
long end = System.currentTimeMillis();
System.out.println("String:"+(end-star));
star = System.currentTimeMillis();
for(int i=0;i<200000;i++){
b.append("b");
}
end = System.currentTimeMillis();
System.out.println("StringBuilder:"+(end-star));
star = System.currentTimeMillis();
for(int i=0;i<200000;i++){
c.append("c");
}
end = System.currentTimeMillis();
System.out.println("StringBuffer:"+(end-star));
}
测试结果
String:17735
StringBuilder:6
StringBuffer:7
测试结论
String+ 确实占用了太多的资源,处理效率非常低下。StringBuilder比StringBuffer更新了同步方法,性能有所提升。
原因分析
我用javap -verbose 查看已经编译好的class文件发现:
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=6, locals=9, args_size=1
0: ldc #16 // String a
2: astore_1
3: new #18 // class java/lang/StringBuilder
6: dup
7: ldc #20 // String b
9: invokespecial #22 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
12: astore_2
13: new #25 // class java/lang/StringBuffer
16: dup
17: ldc #27 // String c
19: invokespecial #29 // Method java/lang/StringBuffer."
init>":(Ljava/lang/String;)V
22: astore_3
23: invokestatic #30 // Method java/lang/System.current
imeMillis:()J
26: lstore 4
28: iconst_0
29: istore 6
31: goto 57
34: new #18 // class java/lang/StringBuilder
37: dup
38: aload_1
39: invokestatic #36 // Method java/lang/String.valueOf
(Ljava/lang/Object;)Ljava/lang/String;
42: invokespecial #22 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
45: ldc #16 // String a
47: invokevirtual #42 // Method java/lang/StringBuilder.
ppend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
50: invokevirtual #46 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
53: astore_1
54: iinc 6, 1
57: iload 6
59: ldc #50 // int 100000
61: if_icmplt 34
64: invokestatic #30 // Method java/lang/System.current
imeMillis:()J
67: lstore 6
69: getstatic #51 // Field java/lang/System.out:Ljav
/io/PrintStream;
72: new #18 // class java/lang/StringBuilder
75: dup
76: ldc #55 // String String:
78: invokespecial #22 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
81: lload 6
83: lload 4
85: lsub
86: invokevirtual #57 // Method java/lang/StringBuilder.
ppend:(J)Ljava/lang/StringBuilder;
89: invokevirtual #46 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
92: invokevirtual #60 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
95: invokestatic #30 // Method java/lang/System.current
imeMillis:()J
98: lstore 4
100: iconst_0
101: istore 8
103: goto 116
106: aload_2
107: ldc #20 // String b
109: invokevirtual #42 // Method java/lang/StringBuilder.
ppend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
112: pop
113: iinc 8, 1
116: iload 8
118: ldc #50 // int 100000
120: if_icmplt 106
123: invokestatic #30 // Method java/lang/System.current
imeMillis:()J
126: lstore 6
128: getstatic #51 // Field java/lang/System.out:Ljav
/io/PrintStream;
131: new #18 // class java/lang/StringBuilder
134: dup
135: ldc #65 // String StringBuilder:
137: invokespecial #22 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
140: lload 6
142: lload 4
144: lsub
145: invokevirtual #57 // Method java/lang/StringBuilder.
ppend:(J)Ljava/lang/StringBuilder;
148: invokevirtual #46 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
151: invokevirtual #60 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
154: invokestatic #30 // Method java/lang/System.current
imeMillis:()J
157: lstore 4
159: iconst_0
160: istore 8
162: goto 175
165: aload_3
166: ldc #27 // String c
168: invokevirtual #67 // Method java/lang/StringBuffer.a
pend:(Ljava/lang/String;)Ljava/lang/StringBuffer;
171: pop
172: iinc 8, 1
175: iload 8
177: ldc #50 // int 100000
179: if_icmplt 165
182: invokestatic #30 // Method java/lang/System.current
imeMillis:()J
185: lstore 6
187: getstatic #51 // Field java/lang/System.out:Ljav
/io/PrintStream;
190: new #18 // class java/lang/StringBuilder
193: dup
194: ldc #70 // String StringBuffer:
196: invokespecial #22 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
199: lload 6
201: lload 4
203: lsub
204: invokevirtual #57 // Method java/lang/StringBuilder.
ppend:(J)Ljava/lang/StringBuilder;
207: invokevirtual #46 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
210: invokevirtual #60 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
213: return
从编译的代码来看,String+的准确操作是:
new StringBuilder()
new String.valueof()
StringBuilder.<init>
StringBuilder.append()
StringBuilder.toString()
而StringBuilder的准确操作是:
StringBuilder.append()
而StringBuffer()的准确操作是:
StringBuffer.append
转自http://alqm1314-126-com.iteye.com/blog/1932879
StringBuilder的append、StringBuffer的append和String str = "a"+"b"的区别?的更多相关文章
- String str=new String("a")和String str = "a"有什么区别?
问:String str=new String("a")和String str = "a"有什么区别? 答:String str = "a" ...
- Java中String直接赋字符串和new String的区别 如String str=new String("a")和String str = "a"有什么区别?
百度的面试官问 String A="ABC"; String B=new String("ABC"); 这两个值,A,B 是否相等,如果都往HashSet里面放 ...
- Java中String str=new String("a")和String str = "a"有什么区别?
Q: String A="ABC"; String B=new String("ABC"); 这两个值,A,B 是否相等,如果都往HashSet里面放,能放下吗 ...
- java中String类、StringBuilder类和StringBuffer类详解
本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html 版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...
- StringBuffer的append方法比“+”高效
在字符串的连接过程中StringBuffer的效率要比String高: string操作代码: String str = new String("welcome to "); st ...
- StringBuilder、StringBuffer和String三者的联系和区别
String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a ...
- String类、StringBuilder类、StringBuffer类
String类是不可变类,创建了一个String对象后,该String对象中的字符序列不能被改变. StringBuilder是字符序列可变的字符串类,提供了一系列修改字符串的方法. StringBu ...
- JAVA String、StringBuilder、和StringBuffer的区别,及如何使用
目录 String类 一.String类的理解和创建对象 二.String类创建的方式 两种创建String对象的区别 测试题 三.String常用方法 四.StringBuffer类 1.Strin ...
- StringBuilder的构造方法和append方法
Java中StringBuilder的构造方法 StringBuilder构造方法: public StringBuilder(): 创建一个空白可变的字符串对象,不含有任何内容 public Str ...
随机推荐
- VUE 使用中踩过的坑
vue如今可谓是一匹黑马,github star数已居第一位!前端开发对于vue的使用已经越来越多,它的优点就不做介绍了,本篇是我对vue使用过程中以及对一些社区朋友提问我的问题中做的一些总结,帮助大 ...
- android基本控件学习-----ProgressBar
ProgressBar(进度条)讲解 一.常用属性和基础使用实例 (1)常用属性: android:max:进度条的最大值 android:progress:进度条已完成进度值 android:pro ...
- 老郭带你学数据结构(C语言系列)2-线性表之动态顺序表
一.基本概念: 线性表:由n个类型相同的数据元素组成的有限序列,记为(a1,a2,--an). 线性表的特征:其中的元素存在这序偶关系,元素之间存在着严格的次序关系. 顺序存储表:线性表中的元素依次存 ...
- hdu 1005(找循环节)
Number Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Linux一些防攻击策略
来自http://www.imooc.com/learn/344
- 将Map<String, List<Map<String,Object>>>进行排序
首先我贴上我的代码,刚开始我也不知道怎么排序还写了一些方法,最后请教群里的大神解决了 public Map<String, List<Map<String,Object>> ...
- NBNS扫描工具nbtscan-unixwiz
NBNS扫描工具nbtscan-unixwiz NBNS是NetBIOS Name Service的缩写,表示NetBIOS名称解析服务.NETBIOS是一种网络协议,用于实现消息通信和资源共享.利用 ...
- mysql事物隔离级别
mysql实现了四种隔离级别 Read Uncommitted(未提交读) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取 ...
- kafka消费者客户端
Kafka消费者 1.1 消费者与消费者组 消费者与消费者组之间的关系 每一个消费者都隶属于某一个消费者组,一个消费者组可以包含一个或多个消费者,每一条消息只会被消费者组中的某一个消费者所消费.不 ...
- delphi如何把一个整数转化为4个十六进制字节
var s:string; len:Integer; AData:TBytes; begin s:=IntToHex(149259,6);//返回6位字符串 len ...