Unveränderlichkeit für Hashcode-Caching in Collections nutzen
Die Unveränderlichkeit von Strings macht sie ideal für die Verwendung als Schlüssel in Hash-basierten Collections wie HashMap
und HashSet
. Da sich der Wert eines Strings niemals ändert, kann sein hashCode()
einmal berechnet und zwischengespeichert werden. Nachfolgende Aufrufe von hashCode()
geben den zwischengespeicherten Wert zurück, was zu erheblichen Leistungsverbesserungen führt, insbesondere wenn Strings häufig als Schlüssel verwendet werden.
Wären Strings veränderlich, könnte sich ihr Hashcode ändern, nachdem sie in eine HashMap
eingefügt wurden, was es unmöglich macht, das Objekt mit dem ursprünglichen Hashcode abzurufen.
Fügen wir dem ImmutableStringDemo.java
Code hinzu, um die String-Verwendung in einer HashMap
zu demonstrieren.
Fügen Sie den folgenden Code in die main
-Methode Ihrer ImmutableStringDemo.java
-Datei ein, nach der Demonstration der Thread-Sicherheit:
// ~/project/ImmutableStringDemo.java
import java.util.HashMap; // Stellen Sie sicher, dass dieser Import am Anfang Ihrer Datei steht
public class ImmutableStringDemo {
private static final String SECURE_PASSWORD = "MySecurePassword123";
static class ThreadSafeTask implements Runnable {
private final String password;
public ThreadSafeTask(String password) {
this.password = password;
}
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getName() + " accessing password: " + password);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
// ... (vorheriger Code für name, str1, str2, str3 und Thread-Sicherheit bleibt hier) ...
String name = "LabexUser";
System.out.println("Initial name: " + name);
String str1 = "Hello";
String str2 = "Hello";
System.out.println("str1: " + str1);
System.out.println("str2: " + str2);
System.out.println("str1 == str2: " + (str1 == str2));
String str3 = new String("Hello");
System.out.println("str3: " + str3);
System.out.println("str1 == str3: " + (str1 == str3));
System.out.println("\n--- Demonstrating Security and Thread Safety ---");
System.out.println("Secure Password: " + SECURE_PASSWORD);
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(new ThreadSafeTask(SECURE_PASSWORD), "Thread-" + (i + 1));
thread.start();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("\n--- Demonstrating Hashcode Caching ---");
HashMap<String, Integer> studentScores = new HashMap<>();
String studentName1 = "Alice";
String studentName2 = "Bob";
String studentName3 = "Alice"; // Dies wird auf dasselbe "Alice" im String-Pool verweisen
studentScores.put(studentName1, 95);
studentScores.put(studentName2, 88);
studentScores.put(studentName3, 92); // Dies aktualisiert den Wert für "Alice"
System.out.println("Student Scores: " + studentScores);
System.out.println("Alice's score: " + studentScores.get("Alice"));
System.out.println("Bob's score: " + studentScores.get("Bob"));
// Demonstrieren, dass auch wenn wir versuchen, einen String zu "ändern", ein neuer erstellt wird
String originalString = "Java";
System.out.println("Original String: " + originalString + ", HashCode: " + originalString.hashCode());
String modifiedString = originalString.concat(" Programming"); // Erstellt einen neuen String
System.out.println("Modified String: " + modifiedString + ", HashCode: " + modifiedString.hashCode());
System.out.println("Original String (after concat): " + originalString + ", HashCode: " + originalString.hashCode());
}
}
Speichern Sie die Datei. Kompilieren und führen Sie das Programm dann erneut aus:
javac ImmutableStringDemo.java
java ImmutableStringDemo
Sie sollten eine Ausgabe ähnlich dieser sehen, einschließlich der HashMap- und Hashcode-Demonstrationen:
Initial name: LabexUser
str1: Hello
str2: Hello
str1 == str2: true
str3: Hello
str1 == str3: false
--- Demonstrating Security and Thread Safety ---
Secure Password: MySecurePassword123
Thread Thread-1 accessing password: MySecurePassword123
Thread Thread-2 accessing password: MySecurePassword123
Thread Thread-3 accessing password: MySecurePassword123
--- Demonstrating Hashcode Caching ---
Student Scores: {Bob=88, Alice=92}
Alice's score: 92
Bob's score: 88
Original String: Java, HashCode: 2301506
Modified String: Java Programming, HashCode: -1479700901
Original String (after concat): Java, HashCode: 2301506
Beachten Sie, wie der Hashcode von originalString
gleich bleibt, auch nachdem concat
aufgerufen wurde, da concat
ein neues String-Objekt zurückgibt und das Original unverändert lässt.