StringBuilder und StringBuffer sind zwei häufig verwendete Klassen zum Manipulieren von Zeichenfolgen. Wie wir alle wissen, ist StringBuilder Thread-Iscure, während StringBuffer Thread-Safe ist. Ersteres wurde von JDK1.5 hinzugefügt und letzteres war in JDK1.0 erhältlich. Analysieren wir ihre internen Implementierungen unten.
1. Vererbungsbeziehung
Public Final Class StringBuffextends AbstractStringBuilderImplements Java.io.Serializable, CharsequencePublic Final Class StringBuilderextends AbstractStringBuilderImplements Java.io.Serializable, Charsequence, Charsequence
Es ist ersichtlich, dass die Erbschaftsbeziehung zwischen den beiden Klassen genau gleich ist. Serialisierbar ist eine serialisierbare Flagge. Die charsequence -Schnittstelle umfasst charat (), länge (), subsequence () und toString ()). Die String -Klasse implementiert auch diese Schnittstelle. Der Fokus liegt hier auf der abstrakten Klasse abstraktem Stringbuilder, der die Implementierung der meisten Operationen von StringBuilder und StringBuffer zusammenfasst.
2.. AbstractStringBuilder
1. Variablen und Konstruktionsmethoden
char [] value; int count; abstractStringBuilder () {} AbstractStringBuilder (int Kapazität) {value = new char [Kapazität];}AbstractStringBuilder verwendet ein char [] -Array, um Zeichenfolgen zu sparen, und die anfängliche Kapazitätsmethode kann während der Konstruktion angegeben werden.
2. Kapazität erweitern
public void sealecapacity (int minimumCapacity) {if (minimumCapacity> 0) sealecapacityInternal (minimumCapacity);} private void sealecapacityInternal (int minimumCapacity) {// Überlauf -bewusstes Code (minimumCapacity - Wert. minimumCapacity) {int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity <0) newCapacity = minimumCapacity; if (newCapacity <0) {if (minimumCapacity <0) // Überlauf -Neue outofMemoryError (); newCapacity = Integer.max_Value; } value = arrays.copyof (Wert, Newcapacity);}Die Expansionsmethode wird letztendlich durch ExpectCapacity () implementiert. Bei dieser Methode wird die Kapazität zunächst auf die ursprüngliche Kapazität plus 2 erweitert. Wenn sie zu diesem Zeitpunkt immer noch geringer ist als die angegebene Kapazität, wird die neue Kapazität auf minimumCapacity eingestellt. Stellen Sie dann fest, ob es überfüllt ist. Wenn es überfüllt ist, setzen Sie die Fähigkeit auf Integer.max_Value. Schließlich ist das Kopieren des Wertwerts offensichtlich ein zeitaufwändiger Betrieb.
A. Append () Methode
public AbstractStringBuilder append (string str) {if (str == null) return appendnull (); int len = str.length (); sealEcapacityInternal (count + len); Str.Getchars (0, Len, Wert, Graf); zählen += len; gib dies zurück; }append () ist die am häufigsten verwendete Methode, es hat viele Formen der Überlastung. Das obige ist einer von ihnen, mit dem Strings angehängt werden. Wenn STR null ist, wird die Methode appendNull () aufgerufen. Diese Methode fügt tatsächlich Zeichen wie 'n', 'u', 'L' und 'L' hinzu. Wenn es sich nicht um Null handelt, erweitern Sie zuerst die Kapazität und rufen Sie dann die Getchars () -Methode von String auf, um STR am Ende des Wertes anzuhängen. Schließlich wird das Objekt selbst zurückgegeben, also kann append () kontinuierlich bezeichnet werden.
3.. StringBuilder
AbstractStringBuilder hat die meisten erforderlichen Methoden implementiert, und StringBuilder und StringBuffer müssen nur aufgerufen werden. Schauen wir uns die Implementierung von StringBuilder an.
1. Konstruktor
public StringBuilder () {Super (16);} public StringBuilder (int -Kapazität) {Super (Kapazität);} public StringBuilder (String str) {Super (str.length () + 16); append (str);} public StringBuilder (charsequence seq) {this (seq.length () + 16); append (seq);}Wie zu sehen ist, beträgt die Standardkapazitätsgröße von StringBuilder 16. Natürlich können Sie auch die anfängliche Kapazität angeben oder dem StringBuilder -Objekt in einer vorhandenen Reihenfolge von Zeichen den Anfangswert zuweisen.
2. Methode append ()
public StringBuilder append (String str) {Super.Append (str); Gibt dies zurück;} public StringBuilder append (charsequence s) {Super.Append (s); Gibt dies zurück;}Es gibt viele Überladungsmethoden für append (), und hier sind zwei davon. Offensichtlich ist hier die Methode in der Elternklasse AbstractStringBuilder, die direkt bezeichnet wird.
3.. ToString ()
public String toString () {// Erstellen Sie eine Kopie und teilenDie Methode toString () gibt ein neues String -Objekt zurück, das den Speicher nicht mit dem ursprünglichen Objekt freigibt. Tatsächlich gilt dies auch für die Substring () -Methode in AbstractStringBuilder.
4. Anfänger
Rührbuffer ähnelt StringBuilder, aber um die Synchronisation zu erreichen, verwenden viele Methoden die lsynchronisierte Modifikation, wie die folgende Methode:
public synchronisierte int länge () {return count;} public synchronisierte StringBuffer append (String str) {toStringCache = null; Super.Append (str); return this;} public synchronisierte void setLength (int newLength) {toStringCache = null; Super.SetLength (NewLength);} Wie Sie sehen können, wird synchronisiert tatsächlich vor der Methode hinzugefügt.
Darüber hinaus gibt es oben einen variablen ToStringCache in den oben genannten Methoden append () und setLength (). Diese Variable wird für den letzten Cache der Methode toString () verwendet. Jedes Mal, wenn der StringBuffer geändert wird, wird diese Variable NULL zugewiesen. Das ToString von StringBuffer lautet wie folgt:
public synchronisierte String toString () {if (toStringCache == null) {toStringCache = arrays.copyofRange (Wert, 0, count); } Neue String zurückgeben (toStringCache, true);}Bei dieser Methode wird es zuerst zwischengespeichert, wenn ToStringCache null ist. Das endgültige zurückgegebene String -Objekt ist etwas anders, und dieser Konstruktor hat einen Parameter wahr. Suchen Sie den Quellcode der Zeichenfolge und schauen Sie sich an:
String (char [] value, boolean share) {// Assert Share: "Unscharter nicht unterstützt"; this.Value = value;}Es stellt sich heraus, dass das von dieser Konstruktionsmethode konstruierte String -Objekt nicht tatsächlich die Zeichenfolge kopiert, sondern den Wert nur auf die Konstruktionsparameter hinweist, nämlich das Sparen von Zeitkopierelementen. Dieser Konstruktor verfügt jedoch über Paketzugriffsberechtigungen und kann im Allgemeinen nicht aufgerufen werden.
Zusammenfassen
Das obige dreht sich alles um diesen Artikel. Ich hoffe, dass es für alle hilfreich sein wird, zwei häufig verwendete Betriebsstringklassen in Java, StringBuilder und StringBuffer zu lernen.