paint-brush
Cambio de claves, pérdida de valorespor@mcsee
544 lecturas
544 lecturas

Cambio de claves, pérdida de valores

por Maximiliano Contieri4m2025/02/24
Read on Terminal Reader

Demasiado Largo; Para Leer

Cuando se utilizan objetos mutables como claves en colecciones con hash, cambiarlos rompe los contratos.
featured image - Cambio de claves, pérdida de valores
Maximiliano Contieri HackerNoon profile picture
0-item


Cambio de claves, pérdida de valores


TL;DR: Cuando se utilizan objetos mutables como claves en colecciones con hash, cambiarlos rompe los contratos.

Problemas 😔

  • Valores perdidos
  • Depuración estricta
  • La violación del principio de la menor sorpresa
  • Comportamiento inesperado

Soluciones 😃

  1. Utilice objetos inmutables como claves.
  2. Anular bien equals/hashCode .
  3. Utilice campos finales (si su idioma lo permite)
  4. Repetición después de la mutación (esta es una solución de sobreingeniería)

Contexto 💬

Cuando se utilizan objetos mutables como claves en colecciones con hash , cambiar la clave después de agregar un objeto relacionado puede hacer que no se pueda recuperar.


Esto sucede porque el código hash cambia y la colección no puede encontrar el objeto en el depósito correcto.

Código de muestra 📖

Incorrecto ❌

 class MutableKey { int id; MutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; MutableKey that = (MutableKey) objectToCompare; return id == that.id; } } MutableKey key = new MutableKey(42); Map<MutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); // The key mutates key.id = 90125; // Now you cannont retrieve the album System.out.println(map.get(key)); // Output: null

Correcto 👉

 class ImmutableKey { private final int id; ImmutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; ImmutableKey that = (ImmutableKey) objectToCompare; return id == that.id; } } ImmutableKey key = new ImmutableKey(42); Map<ImmutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); System.out.println(map.get(key)); // Output: Yes Album

Detección 🔍

  • Semiautomático


Puedes detectar este olor comprobando si utilizas objetos mutables como claves en colecciones basadas en hash.


Las herramientas automatizadas como los linters o las inspecciones IDE también pueden marcar claves mutables.

Etiquetas 🏷️

  • Mutabilidad

Nivel 🔋

  • Intermedio

Por qué es importante la biyección 🗺️

La biyección entre el mundo real y su programa es importante porque garantiza que sus objetos reflejen con precisión las relaciones que se supone que representan.


En el mundo real, las claves suelen ser inmutables (por ejemplo, identificaciones, nombres).


Al modelar estas claves como objetos mutables, se rompe la correspondencia uno a uno entre el mundo real y el programa en el MAPPER .


Cuando se rompe esta biyección utilizando claves mutables, el mapa se vuelve inconsistente, lo que genera fallas de recuperación y un comportamiento inesperado.

Generación IA 🤖

Los generadores de IA podrían crear este olor si generan objetos mutables como claves sin considerar las implicaciones.


Esto rara vez sucede, ya que los generadores de IA sufren de obsesión primitiva .

Detección de IA 🥃

Los generadores de IA pueden detectar este olor con instrucciones para analizar el uso de objetos mutables en colecciones basadas en hash y señalar posibles problemas.


Puedes indicarle a la IA que busque clases sin campos finales o métodos que modifiquen el estado del objeto después de su creación.

¡Pruébalos! 🛠

Recuerde: los asistentes de IA cometen muchos errores

Sin instrucciones adecuadas

Con instrucciones específicas

ChatGPT

ChatGPT

Claudio

Claudio

Perplejidad

Perplejidad

Copiloto

Copiloto

Géminis

Géminis

Búsqueda profunda

Búsqueda profunda

Meta IA

Meta IA

Conclusión 🏁

Cuando se utilizan objetos mutables como claves, se corre el riesgo de romper el contrato entre el estado de la clave y el código hash.


Utilice objetos inmutables para evitar este problema.

Relaciones 👩‍❤️‍💋‍👨

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxiv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxvi

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xviii

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxvi

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xlii

Más información 📕

Aviso legal 📘

Los olores del código son mi opinión .

Créditos 🙏

Foto de Kathyryn Tripp en Unsplash


La propiedad más importante de un programa es si cumple la intención de su usuario.


Coche Hoare



Este artículo es parte de la serie CodeSmell.