In the project development many times we all need to splice the string, that how can efficiently complete the string concatenation. Specify initial capacity
Let's take a look at StringBuilder's source code (JDK7)
public final class StringBuilder extends Abstractstringbuilder implements Java.io.Seriali Zable, charsequence {/** use SERIALVERSIONUID for interoperability/static final long Serialversionuid = 43836
85877147921099L;
/** * Constructs a string builder with no characters in it and a * initial capacity of characters.
* * Public StringBuilder () {super (16); }/** * Constructs a string builder with no characters in it and a * initial capacity
;code>capacity</code> argument.
* * @param capacity the initial capacity. * @throws Negativearraysizeexception if the <code>capacity</code> * argument is less t
Han <code>0</code>
* * Public StringBuilder (int capacity) {super (capacity); }
}
The default constructor method for StringBuilder calls the Abstractstringbuilder (int capacity) Construction method in the parent class Abstractstringbuilder, as follows:
Abstract class Abstractstringbuilder implements Appendable, charsequence {
/**
* The value is used for character s Torage.
* *
char[] value;
/** * The count is the number of
characters used.
*
/int count;
/**
* This no-arg constructor are necessary for serialization of subclasses.
* * Abstractstringbuilder () {
}
/** * Creates an abstractstringbuilder of the
specified capacity.< c15/>*/
abstractstringbuilder (int capacity) {
value = new char[capacity];
}
There is a char[inside the StringBuilder, and the default length of the internal char[] is 16 when calling StringBuilder's parameterless construction method. When we call the Append method of StringBuilder, it is actually the process of filling things in char[].
Public StringBuilder append (String str) {
super.append (str);
return this;
}
Where Super.append is the append (String str) method that invokes Abstractstringbuilder, as follows:
Public Abstractstringbuilder append (String str) {
if (str = null) str = "NULL";
int len = Str.length ();
Ensurecapacityinternal (count + len);
Str.getchars (0, Len, value, count);
Count = Len;
return this;
}
StringBuilder expansion and ArrayList somewhat similar, the specific code is as follows:
/** * This method has the same contract as Ensurecapacity, and but is * never synchronized. * * private void ensurecapacityinternal (int minimumcapacity) {//Overflow-conscious code if (minimumcapacity-val
Ue.length > 0) expandcapacity (minimumcapacity);
}/** * This implements the expansion semantics of ensurecapacity with no * size check or synchronization.
*/void expandcapacity (int minimumcapacity) {int newcapacity = Value.length * 2 + 2;
if (newcapacity-minimumcapacity < 0) newcapacity = minimumcapacity;
if (Newcapacity < 0) {if (minimumcapacity < 0)//overflow throw new OutOfMemoryError ();
newcapacity = Integer.max_value;
} value = arrays.copyof (value, newcapacity); }
StringBuilder the default length is 16, and then, if you want to append the 17th character, what to do.
The answer is to multiply the expansion with arrays.copyof ().
The performance cost of capacity expansion is very serious: one has the cost of the array copy, and the original char[] is also wasted to be GC off. It can be expected that a 129 character length string, after 16,32,64, 1284 times of copying and discarding, has applied for a total of 496 characters in an array, which can hardly be tolerated in high-performance scenarios.
Therefore, it is important to set an initial value rationally. Carefully evaluate the maximum length of the string to be saved before using it. Multiplexing StringBuilder
The Stringbuilder.setlength () method resets its count pointer only, while char[] continues to reuse the source code as follows:
public void SetLength (int newlength) {
if (Newlength < 0)
throw new Stringindexoutofboundsexception ( Newlength);
Ensurecapacityinternal (newlength);
if (Count < Newlength) {for
(; count < newlength; count++)
value[count] = ' I ';
} else {
count = NE Wlength
}
}
ToString () Method:
Public String toString () {
//Create a copy, don ' t share the array return
new String (value, 0, count);
}
ToString () also passes the current count pointer as a parameter to the constructor of string, so you don't have to worry about passing old content that is larger than the new content. It can be seen that StringBuilder is completely reusable.
The specific examples are as follows:
string[] History_steps = Ruledetailinfo.gethistory_steps (). Split (",");
for (String step:history_steps) {
sb.setlength (0);
Sb.append (ruledetailinfo.getbusiness_id ()). Append ("T"). Append (step);
Results.add (Sb.tostring ());
}
+ the difference with StringBuilder
String s = "Hello" + user.getname ();
This line of code is Javac compiled, and indeed equivalent to using StringBuilder, but without a set length.
String s = new StringBuilder (). Append ("Hello"). Append (User.getname ());
However, if this is the case as follows:
String s = "Hello";
The middle inserts some other code
s = S + user.getname ();
Each statement, will generate a new StringBuilder, here there are two StringBuilder, performance is completely different.
If it is s+=i in the circulation body; More ghost, for example:
String str = "";
for (int i=0; i<10000;i++) {
str = i;
}
the difference between StringBuffer and StringBuilder
StringBuffer's source code is as follows (JDK7):
Public final class StringBuffer extends Abstractstringbuilder implements Java.io.Serializable, Charsequence { /** use Serialversionuid from JDK 1.0.2 for interoperability */static final long Serialversionuid = 3388685877147921
107L;
Public StringBuffer () {super (16);
public stringbuffer (int capacity) {super (capacity);
Public StringBuffer (String str) {super (Str.length () + 16);
Append (str);
Public StringBuffer (charsequence seq) {This (Seq.length () + 16);
Append (seq);
synchronized int Length () {return count;
public synchronized int Capacity () {return value.length;
Public synchronized void ensurecapacity (int minimumcapacity) {if (Minimumcapacity > Value.length) {
Expandcapacity (minimumcapacity);
} public synchronized void SetLength (int newlength) {super.setlength (newlength); Public synchronized StringBuffer append (Object obj) {super.append string.valueof (obj));
return this;
Public synchronized StringBuffer append (String str) {super.append (str);
return this; }
......
}
StringBuilder Source:
Public final class StringBuilder extends Abstractstringbuilder implements Java.io.Serializable, Charsequence {
/** use SERIALVERSIONUID for interoperability/static final long serialversionuid = 4383685877147921099L;
Public StringBuilder () {super (16);
public StringBuilder (int capacity) {super (capacity);
Public StringBuilder (String str) {super (Str.length () + 16);
Append (str);
Public StringBuilder (charsequence seq) {This (Seq.length () + 16);
Append (seq);
Public StringBuilder append (Object obj) {return append (string.valueof (obj));
Public StringBuilder append (String str) {super.append (str);
return this;
}//appends the specified string builder to this sequence.
Private StringBuilder Append (StringBuilder sb) {if (SB = null) return append ("null");
int len = Sb.length (); int newcount = COUNT + len;
if (Newcount > Value.length) expandcapacity (Newcount);
Sb.getchars (0, Len, value, count);
Count = Newcount;
return this;
Public StringBuilder append (StringBuffer sb) {super.append (SB);
return this; }
......
}
StringBuffer and StringBuilder are inherited from the Abstractstringbuilder, the only difference is that the StringBuffer function has synchronized keyword. Summary
StringBuilder is not thread-safe, so it cannot be shared in a multithreaded environment. StringBuilder must specify its initial size when used, and in the case of high performance requirements, you can consider using a threadlocal cache reusable StringBuilder.