2009-03-11 14 views
6

Tengo dos tipos de objetos en mi aplicación donde cada objeto de un tipo tiene exactamente un objeto correspondiente del otro tipo.¿Alguna desventaja al usar objetos arbitrarios como claves Map en Java?

La opción obvia para realizar un seguimiento de esta relación es un Map<type1, type2>, como un HashMap. Pero de alguna manera, soy sospechoso. ¿Puedo usar un objeto como clave en el Mapa, pasarlo, tenerlo sentado en otra colección, también, y recuperar su compañero del Mapa en cualquier momento?

Después de crear un objeto, todo lo que estoy pasando es un identificador, ¿verdad? Entonces probablemente no hay problema allí. ¿Qué sucede si serializo y deserializo la clave?

¿Alguna otra advertencia? ¿Debería usar algo más para correlacionar los pares de objetos, como un número que genero yo mismo?

Respuesta

22
  1. Las necesidades clave para implementar .equals() y .hashCode() correctamente
  2. La clave no debe ser cambiado en cualquier forma que cambia su .hashCode() valor, mientras que se utiliza como clave
  3. Lo ideal sería que cualquier objeto usado como una clave en un HashMap debe ser inmutable. Esto garantizaría automáticamente que 2. siempre se mantenga como verdadero.
  4. Los objetos que de lo contrario se podrían convertir en GC podrían guardarse cuando se usan como clave y/o valor.
0

Cualquier objeto puede ser una clave de mapa. Lo importante aquí es asegurarse de anular .equals() y .hashCode() para cualquier objeto que se utilizará como claves de mapa.

La razón por la que haces esto es que si no lo haces, equals se entenderá como igualdad de objetos, y la única forma en que podrás encontrar claves de mapa "iguales" es tener un control sobre el objeto original sí mismo.

Sobreescribes hashcode porque tiene que ser coherente con iguales. Esto es para que los objetos que ha definido sean iguales a hash de forma idéntica.

0

Los puntos de falla son las funciones hashcode y equal. Si no producen valores de retorno consistentes y adecuados, el mapa se comportará de manera extraña. Effective Java tiene una sección completa y es sumamente recomendable.

7

que tienen dos tipos de objetos en mi solicitud donde cada objeto de un tipo tiene exactamente un correspondiente objeto de la otra clase.

Esto realmente suena como una relación has-a y por lo tanto podría implementarse utilizando un atributo simple.

+0

Estoy de acuerdo. Sin embargo, el resto de la pregunta aún podría ser útil para otros. (o incluso para @OP si esa no es una alternativa por alguna razón) –

+0

@saua Estoy de acuerdo contigo. Solo pensé que señalaría la aplicabilidad de los atributos en este contexto particular. –

1

Puede usar un Mapa estándar, pero al hacerlo guardará referencias fuertes a sus objetos en el Mapa. Si se hace referencia a sus objetos en otra estructura y necesita el Mapa para vincularlos, considere usar WeakHashMap.

Y, por cierto, no es necesario anular equals y hashCode a menos que tenga que considerar varias instancias de un objeto como iguales ...

1

¿Puedo utilizar un objeto como clave en el mapa, pasarlo, tenerlo también en otra colección y recuperarlo del mapa en cualquier momento?

Sí, no hay problema aquí en absoluto.

Después de crear un objeto, todo lo que estoy pasando es un identificador, ¿verdad? Entonces probablemente no hay problema allí. ¿Qué sucede si serializo y deserializo la clave?

Así es, solo está aprobando una referencia: todos señalarán el mismo objeto real. Si serializas o deserializas el objeto, eso crearía un nuevo objeto. Sin embargo, si su objeto implementa equals y hashCode correctamente, aún debería poder utilizar el nuevo objeto deserializado para recuperar elementos del mapa.

¿Alguna otra advertencia? ¿Debería usar algo más para correlacionar los pares de objetos, como un número que genero yo mismo?

En cuanto a las advertencias, sí, no se puede cambiar nada que provoque que el código hash del objeto cambie mientras el objeto está en el mapa.

3

Depende de la aplicación de la hoja a elegir:

  • HashMap utiliza equals() yhashCode(). Por defecto (en Object) estos se basan en la identidad del objeto, que funcionará bien a menos que se serialice/deserialice. Con una implementación adecuada de equals() y hashCode() en función del contenido del objeto, no tendrás problemas, siempre y cuando no lo modifiques mientras sea una clave en un mapa hash.

  • TreeMap utiliza compareTo(). No hay una implementación predeterminada, por lo que debe proporcionar una. Se aplican las mismas limitaciones que para implementar hashCode() y equals() arriba.

0

Puede considerar Google Collection BiMap.

Cuestiones relacionadas