-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathessay17.txt
99 lines (86 loc) · 3.53 KB
/
essay17.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Java Essay Serials 1 - Java Basics - 17, String,StringBuilder and StringBuffer.
They are all used to process strings, but have several differences.
1. The class String is an immutable class, while the class StringBuilder and String StringBuffer are mutable. This had been mentioned many times in this Essay Serial.
Some write the following code to 'prove' the class String is mutable:
String str = "Hello ";
str += "World!";
In fact, the compiler interpretes the above code as below:
String str = "Hello ";
StringBuffer sb = new StringBuffer(str);
sb.append("World!");
str = sb.toString();
Here we can see that str firstly refers to "Hello ", then refers to a new string instance "Hello World!". Only the address is changed, the string instance never changed.
2. As for the performance, StringBuilder ranks 1st, then StringBuffer, then String.
To test this, we can simply append each string 10000 times:
String s = "hello ";
long start0 = System.currentTimeMillis();
for (int i=0; i<10000; i++) {
s += "world";
}
long end0 = System.currentTimeMillis();
System.out.println("String:"+(end0-start0));
StringBuffer sb = new StringBuffer("hello ");
long start1 = System.currentTimeMillis();
for (int i=0; i<10000; i++) {
sb.append("world");
}
long end1 = System.currentTimeMillis();
System.out.println("StringBuffer:"+(end1-start1));
StringBuilder sbd = new StringBuilder("hello ");
long start2 = System.currentTimeMillis();
for (int i=0; i<10000; i++) {
sbd.append("world");
}
long end2 = System.currentTimeMillis();
System.out.println("StringBuilder:"+(end2-start2));
The program outputs:
String:957
StringBuffer:2
StringBuilder:1
3. The class String overrides the method equals() of Object class, but StringBuilder and StringBuffer do not do that. So, using StringBuilder and StringBuffer in collections would arise issues.
For example:
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1.equals(s2));
StringBuffer sbf1 = new StringBuffer("Hello");
StringBuffer sbf2 = new StringBuffer("Hello");
System.out.println(sbf1.equals(sbf2));
StringBuilder sbd1 = new StringBuilder("Hello");
StringBuilder sbd2 = new StringBuilder("Hello");
System.out.println(sbd1.equals(sbd2));
This program would output:
true
false
false
4. The class String is thread-safe, StringBuffer is thread-safe, while StringBuilder is thread-unsafe. Because StringBuider is fastest, so we usualy use it in single thread environment.
For example:
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 10; i++){
new Thread(()-> {
for (int j = 0; j < 1000; j++){
stringBuilder.append("a");
}
}
).start();
}
Thread.sleep(100);
System.out.println(stringBuilder.length());
If we use StringBuilder in a multi-thread environment, to create ten threads which each append 'a' to an existing string buffer 1000 times. We expect the length of string buffer be 10000 when the program ends.
But the result is:
9386
Run it again, this time outputs:
9984
The result is not stable, due to the 'thread-unsafe' nature of StringBuilder.
As a comparison, we can run the same program on StringBuffer:
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 10; i++){
new Thread( ()-> {
for (int j = 0; j < 1000; j++){
stringBuffer.append("a");
}
}
).start();
}
Thread.sleep(100);
System.out.println(stringBuffer.length());
The output is always 10000, meaning that it is thread-safe.