Vorwort
In diesem Artikel wird hauptsächlich die relevanten Inhalte zur JDK -Quellcodeanalyse, StringBuilder und StringBuffer vorgestellt. Es wird für Ihre Referenz und Ihr Lernen geteilt. Ich werde unten nicht viel sagen. Schauen wir uns die detaillierte Einführung gemeinsam an.
Anweisung der Zeichenfolgeklasse
Public Final Class String implementiert java.io.serializable, vergleichbar <string>, charsequence {…}Die String -Klasse verwendet einen endgültigen Modifikator, um anzuzeigen, dass sie nicht vererbt werden kann. Gleichzeitig implementiert es auch drei Schnittstellen, wodurch die serialisierbare Schnittstelle implementiert wird, um anzuzeigen, dass die String -Klasse serialisiert werden kann. Das Implementieren der vergleichbaren <T> -Schingrenze bietet hauptsächlich eine Vergleichsmethode zum Vergleich von String -Zeichenfolgen. Implementiert auch die Charsequence -Schnittstelle, die darstellt, dass char eine lesbare Sequenz wert ist (Charbuffer, Segment, String, StringBuffer und StringBuilder implementiert auch die charsequence -Schnittstelle).
String Hauptfelder und Attributbeschreibungen
/*Zeichenarray -Wert, das die tatsächlichen Zeichen in der Zeichenfolge speichert /*Der Hash -Wert des String -Standardwerts 0*//*Ein Komparator, der zum Sortieren von String -Objekten verwendet wird, verwendet die VergleicheToignoreCase -Methode*/public static endgültig Vergleiche <string> case_insensitiv_order = new CaseinsensitiveComparator ();
Analyse der Teilmethode an String
Die String -Klasse bietet eine Reihe von Konstruktoren, und einige von ihnen werden nicht mehr empfohlen, wie in der folgenden Abbildung gezeigt:
Konstruktor
Hier sind die Implementierungen von zwei häufig verwendeten Konstruktoren:
// String str = new String ("123") public String (String Original) {this.value = original.Value; this.hash = original.hash;} // String str3 = new String (new char [] {'1', '2', '3'}); public String (char value []) {// den Zeichenarraywert kopieren, um dies zu bewerten.Value = arrays.copyof (value, value.Length); }boolean gleich (Objekt Anobject)
Die String -Klasse überschreibt die Equals -Methode, um diese Zeichenfolge mit dem angegebenen Objekt zu vergleichen. Das Ergebnis ist wahr, wenn der Parameter nicht null ist und ein Zeichenfolgenobjekt ist, das dieselbe Zeichensequenz wie dieses Objekt darstellt.
public boolean Equals (Object AnObject) {// Vergleiche Objektreferenzen direkt und zurückgeben, wenn (this == anObject) {return true; } // Vergleichen Sie die Zeichensequenz des aktuellen Objekts mit Anobject -Wert, wenn (AnObject Instance von String) {String AnotherStRing = (String) AnObject; int n = value.length; if (n == AnotherString.Value.length) {char v1 [] = Wert; char v2 [] = anotherstring.Value; int i = 0; while (n--! = 0) {if (v1 [i]! = v2 [i]) return false; i ++; } Return true; }} return false; }int vergleicheto (String aTherString)
Vergleichen Sie die Charaktersequenz von zwei Strings Stück für Stück. Wenn ein Bit -Zeichen nicht gleich ist, geben Sie den Unterschied im Unicode -Wert der beiden Zeichen dieses Bits zurück. Alle Bits sind gleich, berechnen Sie die Differenz in der Länge der beiden Saiten. Wenn die beiden Saiten gleich sind, kehren Sie 0 zurück.
public int vergleicheto (string anotherstring) {int len1 = value.length; int len2 = Anotherstring.Value.Length; // Nehmen Sie die Länge einer Zeichenfolge mit einer kleineren Länge in Lim = Math.min (Len1, Len2); char v1 [] = Wert; char v2 [] = anotherstring.Value; int k = 0; while (k <lim) {// den Zeichensequenzwert der beiden Zeichenfolgen nacheinander vergleiche. Wenn es nicht gleich ist, geben Sie die Differenz zwischen dem Unicode der beiden Zeichen an dieser Position zurück. Char c1 = v1 [k]; char c2 = v2 [k]; if (c1! = c2) {return c1 - c2; // den Unterschied zwischen Unicode} K ++ zurückgeben; } // Alle Bits einer kleineren Zeichenfolge werden verglichen, und die Differenz zwischen den Längen der beiden Zeichenfolgen wird zurückgegeben // Wenn die beiden Zeichenfolgen gleich sind, beträgt der Unterschied zwischen den Längen 0, dh derselben String gibt 0 zurück. Len1 - Len2; } Die Vergleiche -Methode (String) wird ähnlich implementiert. Der obere und untere Fall von Zeichen wird während des Vergleichs ignoriert, und die Implementierungsmethode lautet wie folgt:
public int compare (String S1, String S2) {int n1 = s1.length (); int n2 = s2.Length (); int min = math.min (n1, n2); für (int i = 0; i <min; i ++) {char c1 = s1.charat (i); char c2 = s2charat (i); if (c1! = c2) {c1 = charakter.touppercase (c1); c2 = charakter.touppercase (c2); if (c1! = c2) {c1 = charakter.tolowerCase (c1); C2 = Zeichen.TolowerCase (C2); if (c1! }}}} return n1 - n2; }Native String praktikum ()
Wenn die Praktikantenmethode aufgerufen wird, wird der String im Pool zurückgegeben, wenn der Pool bereits eine Zeichenfolge enthält, die diesem String -Objekt enthält (bestimmt mit der Equals (Object) -Methode). Fügen Sie dieses String -Objekt ansonsten dem Pool hinzu und geben Sie eine Referenz auf dieses Zeichenfolgenobjekt zurück.
Alle buchstäblichen Zeichenfolgen und Stringzuweisungen konstante Ausdrücke werden unter Verwendung der Internetmethode betrieben, z. B. String Str1 = "123";
Zeichenfolgespeicherort: Konstant Pool oder Haufen
String -Objekte können direkt über Literale oder Konstruktoren erstellt werden. Was ist der Unterschied?
1. Saitenobjekte, die durch wörtliche oder wörtliche Saiten durch "+" -Plennung erzeugt werden, werden im konstanten Pool gespeichert. Wenn der konstante Pool während der tatsächlichen Schöpfung vorhanden ist, wird die Referenz direkt zurückgegeben. Wenn es nicht existiert, wird das String -Objekt erstellt.
2. Erstellen Sie ein String -Objekt mit dem Konstruktor und erstellen Sie ein String -Objekt direkt im Haufen
3. Rufen Sie die Praktikum -Methode auf und geben Sie das Objekt zurück in den konstanten Pool (falls dies nicht vorhanden ist, es wird in den konstanten Pool gegeben, und wenn es vorhanden ist, wird sie in die Referenz zurückgegeben).
Das Folgende ist ein Beispiel für die Speicherzuweisung von String -Objekten:
String str1 = neuer String ("123"); String str2 = "123"; String str3 = "123"; String str4 = str1.intern (); System.out.println (str1 == str2); // False Str1 erstellt ein Objekt im Heap, Str2 erstellt ein Objekt im konstanten Poolsystem.out.println (str2 == str3); // True Str2 erstellt ein Objekt im konstanten Pool, Str3 gibt direkt eine Referenz auf das von str2 erstellte Objekt zurück, so dass Str2 und str3 auf dasselbe Objekt im konstanten Poolsystem verweisen.OUT.println (str4 == str3); // True Str4 gibt ein Objekt mit einem Wert von "123" im konstanten Pool zurück, so dass Str4, str2 und str3 gleich sind.Über das Beispiel für Zeichenfolgenstiche:
public class StringTest {public static Final String x = "ABC"; // Konstante x @test public void test () {String str5 = new String ("ABC"); String str6 = str5+"def"; // String str7 = "abc"+"def" erstellen; // Konstante Pool String str8 = x+"def"; // x ist eine Konstante und der Wert ist festgelegt, sodass der Wert von x+"def" auf ABCDEF eingestellt wurde. Tatsächlich entspricht der Code nach der Kompilierung String str8 = "abcdef" String str9 = "abc"; String str10 = str9+"def"; //System.out.println(str6==str7); // False System.out.println (str8 == str7); // true system.out.println (str10 == str7); // False System.out.println (x == str9); //WAHR} }Der dekompilierte Code wird auf einen Blick klar sein:
Die Speicherallokation ist wie folgt:
String, StringBuffer, StringBuilder
Da das Eigenschaftswert [] Charakterarray für das interne, interne Anhaltspunkt von Saitenstaaten, mit dem endgültigen geändert wird:
/** Der Wert wird für den Zeichenspeicher verwendet. */privater endgültiger Charwert [];
Es zeigt an, dass es nach der Zuordnung geändert werden kann. Daher glauben wir, dass das String -Objekt nach dem Erstellen unveränderlich ist. Wenn Sie während der Entwicklung auf häufige Spleißstringvorgänge stoßen, werden häufig neue Zeichenfolgen generiert, die ineffizient sind. Java bietet zwei weitere Klassen: StringBuffer und StringBuilder, mit denen dieses Problem gelöst wird:
Schauen Sie sich den folgenden Code an:
String str1 = "123"; String str2 = "456"; String str3 = "789"; String str4 = "123" + "456" + "789"; // Fügen Sie Konstanten hinzu, der Compiler erkennt automatisch String str4 = "123456789" String str5 = str1 + str2 + str3; // Sticket -String -Variablen, es wird empfohlen, StringBuilder StringBuilder sb = new StringBuilder () zu verwenden. sb.Append (str1); sb.Append (str2); Sb.Append (STR3);
Das Folgende ist die Implementierung der StringBuilder -Klasse, die nur einige der analysierten Code abfängt:
öffentliche endgültige Klasse StringBuilder erweitert abstractStringBuilder implementiert java.io.serializable, charsequence {// split String @Override public StringBuilder Append (String Str) {// Die übergeordnete Klasse AbstractStringBuilder.Append Super.Append (STR); gib dies zurück; }} Abstract Class AbstractStringBuilder implementiert angehört, charsequence { / *** Das Zeichenarray, das Zeichenfolgen speichert, unterscheidet sich von String-Klasse* / char [] Wert; /*** Die Anzahl ist die Anzahl der verwendeten Zeichen. */ int count; public AbstractStringBuilder append (string str) {if (str == null) return appendnull (); int len = str.length (); // Überprüfen Sie, ob die Kapazität auf sealEcapacityInternal (count + len) erweitert werden muss. // die String str. zählen += len; Geben Sie diese zurück;} Arrays.copyof (Wert, NewCapacity (minimumCapacity)); }} // StringBuilder-Erweiterung private int NewCapacity (int mincapacity) {// Überlauf-Consbewusste Code // Berechnen Sie die Erweiterungskapazität // Die Standardlänge der Standardausdehnung wird um das 2-fache der ursprünglichen Zahl (Wert []) erweitert und dann 2 zur Regel hinzugefügt. Warum 2 hinzufügen? int newcapacity = (value.length << 1) + 2; if (newcapacity - mincapacity <0) {newCapacity = mincapacity; } return (NewCapacity <= 0 || max_array_size - NewCapacity <0)? Hugenkapazität (Hackigkeit): Newcapacity; }}Gleiches gilt für StringBuffer und StringBuilder. Das interne Wert [] -Scharray ist veränderlich. Der einzige Unterschied besteht darin, dass StringBuffer Thread-Safe ist. Es synchronisiert alle Methoden. StringBuilder ist Thread-nicht sicher. Daher wird StringBuffer, wenn Multi-Thread-Betriebs- und Freigabe-String-Variablen Variablen, für die Verarbeitung von String-Spleißen bevorzugt. Andernfalls kann StringBuilder verwendet werden. Schließlich bringt die Thread -Synchronisation auch einen bestimmten Verbrauch.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.