Aprovechar la Inmutabilidad para el Caché de Hashcode en Colecciones
La inmutabilidad de los Strings los hace ideales para su uso como claves en colecciones basadas en hash como HashMap y HashSet. Dado que el valor de un String nunca cambia, su hashCode() puede calcularse una vez y almacenarse en caché. Las llamadas posteriores a hashCode() devolverán el valor almacenado en caché, lo que generará mejoras significativas de rendimiento, especialmente cuando los Strings se utilizan frecuentemente como claves.
Si los Strings fueran mutables, su código hash podría cambiar después de ser insertados en un HashMap, lo que haría imposible recuperar el objeto utilizando el código hash original.
Agreguemos código a ImmutableStringDemo.java para demostrar el uso de String en un HashMap.
Agregue el siguiente código al método main de su archivo ImmutableStringDemo.java, después de la demostración de seguridad en hilos (thread safety):
// ~/project/ImmutableStringDemo.java
import java.util.HashMap; // Asegúrese de que esta importación esté al principio de su archivo
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) {
// ... (el código anterior para name, str1, str2, str3 y seguridad en hilos permanece aquí) ...
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"; // Esto se referirá al mismo "Alice" en el String pool
studentScores.put(studentName1, 95);
studentScores.put(studentName2, 88);
studentScores.put(studentName3, 92); // Esto actualizará el valor para "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"));
// Demostrar que incluso si intentamos "cambiar" un String, se crea uno nuevo
String originalString = "Java";
System.out.println("Original String: " + originalString + ", HashCode: " + originalString.hashCode());
String modifiedString = originalString.concat(" Programming"); // Crea un nuevo String
System.out.println("Modified String: " + modifiedString + ", HashCode: " + modifiedString.hashCode());
System.out.println("Original String (after concat): " + originalString + ", HashCode: " + originalString.hashCode());
}
}
Guarde el archivo. Luego, compile y ejecute el programa nuevamente:
javac ImmutableStringDemo.java
java ImmutableStringDemo
Debería ver una salida similar a esta, incluyendo las demostraciones de HashMap y hashcode:
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
Observe cómo el hash code de originalString permanece igual incluso después de llamar a concat, porque concat devuelve un objeto String nuevo, dejando el original intacto.