Die Geschichte des einfachen String-Vergleichs in Java

Dieser Artikel ist der dritte Tag des Shizudai Information LT-Turnier-Adventskalenders 2019.

Einführung

Es ist eine einfache Geschichte. Es ist leicht zu lesen, ob Java vorerst normalisiert werden kann. Wenn Sie Zeichenfolgen verglichen haben, können Sie diese vorerst lesen.

Rezension(?)

Vergleichen Sie beim Vergleichen von Zeichenfolgen in Java nicht mit "==". Verwenden Sie die Methode String # equals.

public class Test {
	public static void main(String[] args) {
		String a = "HelloWorld";
		String b = "Hello";
		b += "World";

		System.out.println(a == b);        // false
		System.out.println(a.equals(b));   // true
	}
}

Warten Sie eine Minute, "==" wird wahr sein

public class Test {
	public static void main(String[] args) {
		String a = "HelloWorld";
		String b = "HelloWorld";

		System.out.println(a == b);       // true
		System.out.println(a.equals(b));  // true
	}
}

Warum?

Mechanismus von "=="

JVM "==" Wird oft als Vergleich der Adresspositionen bezeichnet, aber schauen wir uns das genauer an.

In Java wird "==" zur Kompilierungszeit häufig in eine der JVM-Anweisungen konvertiert, z. B. "if_acmpne" oder "if_acmpeq".

In einer JVM werden beim Kompilieren einer Java-Datei viele Klassendateien generiert, oder? Die Java Virtual Machine (JVM) interpretiert die Klassendatei und führt sie aus. Klassendateien haben ein Format, das viele Menschen nicht lesen können (und selten lesen), aber auf einer JVM (Computer) leichter zu lesen sind. Da die JVM ein komplexes Programm durch Kombinieren mehrerer einfacher Anweisungen realisiert, wird in Java häufig nur eine Anweisung in mehrere Anweisungen konvertiert. image.png

JVM-Befehl und Operandenstapel

Welche Art von Anweisung dann "if_acmpne" oder "if_acmpeq" ist, ist eine Anweisung, die zwei aus dem Operandenstapel herausnimmt, prüft, ob sie übereinstimmen, und zur Zeile des angegebenen Programms springt.

Operandenstapel ……? Die JVM wird als Stapelmaschine bezeichnet und verwendet keine Register, sondern ein Gerät, das als "Stapel" bezeichnet wird, um verschiedene Operationen auszuführen.

Der Operandenstapel ist wie ein Arbeitsbereich. Es wird häufig verwendet, da es für Operationen mit vier Regeln genau richtig ist. (Umgekehrte polnische Notation usw.)

Zum Beispiel können 5 + 12 durch den folgenden Mechanismus berechnet werden. image.png

Der Operandenstapel in Java enthält jedoch nur ein Element mit bis zu 32 Bit.

Wenn ein Zeichen durch Java dargestellt wird, wird ein Element (= 32 Bit) dieses Operandenstapels verbraucht. Die Zeichenfolge hat eine variable Größe. Manchmal behandeln wir ein Zeichen und manchmal Hunderte von Zeichen wie in diesem Artikel. Mit anderen Worten, ein Element des Operandenstapels (= 32 Bit) kann überhaupt nicht alle Zeichen verarbeiten.

Daher wird die Zeichenfolge in einem anderen Speicher gespeichert, und die Adresse dieses Speichers (Adresse auf dem Computer) wird im Operandenstapel gespeichert. Infolgedessen reicht ein Element des Operandenstapels (= 32 Bit) aus.

Wie bereits erwähnt, werden "if_acmpne" und "if_acmpeq" aus dem Operandenstapel übernommen. Wenn sie für "if_acmpeq" gleich und für "if_acmpne" nicht gleich sind, springen sie zu einer anderen angegebenen Zeile. (Springen ist wie ein gewöhnlicher GOTO-Befehl) image.png

Mit anderen Worten, im Fall von "if_acmpeq" wird ein Sprungbefehl erzeugt, wenn die Nummern der Adressen auf dem Operandenstapel gleich sind. Im zweiten Quellcode auf dieser Seite ("Moment mal") wurde "Hello World" unter derselben Adresse gespeichert, sodass es als "true" angezeigt wird.

Um wahr zu sein ...

Wird es am selben Ort aufbewahrt?

Das ist es.

Also, was denkst du wird das sein? Bitte verzeihen Sie, dass die Benennung angemessen ist

public class Test {
	public static void main(String[] args) {
		String a = "HelloWorld";
		method1(a);
	}
	
	public static void method1(String c) {
		String k = "HelloWorld";
		System.out.println(k == c);
	}
}

Die Antwort ist "wahr".

Klasse konstante Fläche

Java-Klassendateien haben einen konstanten Bereich. In diesem konstanten Bereich werden beim Kompilieren hauptsächlich Zeichenfolgen usw. gespeichert. Dinge wie magische Zahlen und magische Zeichenfolgen (?) Werden in diesem konstanten Bereich gespeichert und in den Speicher geladen und verwendet, wenn die JVM die Klassendatei liest. Zum Beispiel

System.out.println("Hello Ja! Ja!");

Zum Beispiel "Hallo Ja! Ja!" Wird im konstanten Bereich gespeichert und die Zeichenfolge wird von dort gelesen.

Außerdem ist der Java-Compiler so intelligent, dass selbst wenn dieselbe Zeichenfolge zweimal angezeigt wird, sie aus demselben konstanten Bereich gelesen wird, wenn sie zuvor mehrmals verwendet wurde. Mit anderen Worten, im vorherigen Code waren die Adressen, auch wenn die Methoden unterschiedlich waren, dieselben, da sie sich auf die Zeichenfolge "Hello World" im konstanten Bereich derselben Klasse bezogen.

Wenn Sie sich den konstanten Bereich der Klassendatei ansehen, wird "Hallo Welt" ordnungsgemäß gespeichert. image.png

Nebenbei habe ich im ersten Quellcode auf dieser Seite die Zeichenfolgen absichtlich in zwei Teile geschrieben, "Hallo" und "Welt", um den Speicherbereich zu trennen. Der Java-Compiler scheint nicht so viel zu tun. C-Compiler tun dies häufig.

Was ist mit gleich?

Es wird von der String-Klasse überschrieben und ist ein Code, der den Inhalt fest vergleicht Der Bildcode sieht wie folgt aus. Nicht die ursprüngliche Mutter.

@Override
public boolean equals(String str) {
	if(this.length() != str.length()) {
		return false;
	}
	for(int i = 0; i < str.length(); i++) {
		if(this.charAt(i) != str.charAt(i)) {    //Sie können jedes beliebige n-te Zeichen mit charAt abrufen
			return false;
		}
	}
	return true;
}

Es ist linear und vergleicht die Zeichen einzeln von vorne. Es gibt kein Problem, da ein Zeichen in 32 Bit passt.

Zusammenfassung

Verwenden Sie beim Vergleichen von Zeichenfolgen die Methode equals. Wenn es mit "==" wahr wird, wird es an derselben Stelle gespeichert. Hmmm.

Der Adventskalender von morgen ist auch gut! .. Adventskalender des Shizudai Information LT-Turniers 2019

Recommended Posts

Die Geschichte des einfachen String-Vergleichs in Java
Die Geschichte des Schreibens von Java in Emacs
Die Geschichte eines gewöhnlichen Othello in Java
Die Geschichte des Lernens von Java in der ersten Programmierung
[Java] Geschwindigkeitsvergleich der Zeichenfolgenkombination
[Java Edition] Geschichte der Serialisierung
[Java] Korrekter Vergleich des String-Typs
Holen Sie sich das Ergebnis von POST in Java
In Bezug auf den Vergleich der Zeichenfolgentypäquivalenz in Java
Die Geschichte, das Verhalten von String durch Passieren von Java nicht zu kennen
[Java] Behandlung von Java Beans in der Methodenkette
Über die Idee anonymer Klassen in Java
Eine Geschichte über das JDK in der Java 11-Ära
Die Geschichte, zu vergessen, eine Datei in Java zu schließen und zu scheitern
Messen Sie die Größe eines Ordners mit Java
[Java] Vergleich von Zeichenketten und && und ||
[Java] Ermittelt die Länge der Ersatzpaarzeichenfolge
[Java] Der verwirrende Teil von String und StringBuilder
[Hinweis] Java: Messen Sie die Geschwindigkeit der Zeichenfolgenverkettung
Spüren Sie den Lauf der Zeit auch in Java
Die Geschichte des Erwerbs von Java Silver in zwei Monaten von völlig unerfahrenen.
Importieren Sie Dateien derselben Hierarchie in Java
[Java] Äquivalenzvergleich, bei dem Anfänger beim Vergleich von Zeichenfolgen fehlschlagen. Möglicherweise sind Sie sich des Fehlers nicht einmal bewusst! ??
Zeichenfolgenvergleich: Ich war in das Skill-Check-Problem von Paisa verwickelt
Rufen Sie die URL des HTTP-Umleitungsziels in Java ab
Der Vergleich von enum ist == und gleich ist gut [Java]
Die Geschichte einer illegalen staatlichen Ausnahme in Jetty.
[Java] Holen Sie sich die Datei unabhängig von der Umgebung in das JAR
Ändern Sie die Speicherqualität von JPEG-Bildern in Java
Die Geschichte von dto, dao-like mit Java, SQLite
Fassen Sie die zusätzlichen Elemente der optionalen Klasse in Java 9 zusammen
Die Geschichte, dass .java auch in Unity 2018 erstellt wurde
Java-Implementierung von Tri-Tree
Wurde im Basisjahr der Java-Kalenderwoche durchgeführt
Eine kurze Erklärung der fünf Arten von Java Static
Fügen Sie die Datei in die Eigenschaften eines Strings mit Spring XML-Konfiguration ein
20190803_Java & k8s on Azure Die Geschichte vom Festivalbesuch
Die Geschichte des Werfens von BLOB-Daten von EXCEL in DBUnit
[Java] Versuchen Sie, die Elemente der Json-Zeichenfolge mithilfe der Bibliothek zu bearbeiten
Zählen Sie die Anzahl der Stellen nach dem Dezimalpunkt in Java
So leiten Sie den letzten Tag des Monats in Java ab
Die Geschichte, Java mithilfe der BitBucket-Pipeline nach Heroku zu bringen
Greifen Sie mit Java auf die Netzwerkschnittstelle zu
[Java] Löschen Sie die Elemente von List
Errate den Zeichencode in Java
Verschiedene Methoden der Java String Klasse
Geben Sie den Java-Speicherort in eclipse.ini an
Die Geschichte von Java Gold SE8
Java-Vergleich mit der compareTo () -Methode
Entpacken Sie die Zip-Datei in Java
Die Geschichte von @ViewScoped, die Speicher verschlingt
Verschiedene Methoden der String-Klasse
Liste der in Java 9 hinzugefügten Mitglieder
Analysieren der COTOHA-API-Syntaxanalyse in Java
Liste der in Java 9 hinzugefügten Typen
Reihenfolge der Verarbeitung im Programm
Ich habe die Quelle von String gelesen