2010-04-29 28 views
8

Necesito crear un conjunto de objetos. La preocupación es que no quiero basar el hashing o la igualdad en el hashCode de los objetos e igualar la implementación. En cambio, quiero que el código hash y la igualdad se basen solo en la identidad de referencia de cada objeto (es decir, el valor del puntero de referencia).conjunto de referencia de objeto en java

No estoy seguro de cómo hacer esto en Java.

El razonamiento detrás de esto es que mis objetos no implementan equals o hashCode de manera confiable, y en este caso la identidad de referencia es lo suficientemente buena.

Respuesta

19

Supongo que java.util.IdentityHashMap es lo que está buscando (tenga en cuenta que no hay IdentityHashSet). Buscar la documentación de la API:

Esta clase implementa la interfaz Map con una tabla hash, utilizando la igualdad de referencia en lugar del objeto igualdad cuando se comparan las teclas (y valores). En otras palabras, en un IdentityHashMap, dos claves k1 y k2 se consideran iguales si y solo si (k1==k2). (En condiciones normales Map implementaciones (como HashMap) dos llaves k1 y k2 se consideran iguales si y sólo si (k1==null ? k2==null : k1.equals(k2)).)

Esta clase no es un propósito general Map aplicación! Si bien esta clase implementa la interfaz Map, infringe intencionalmente el contrato general de Map, que exige el uso del método equals al comparar objetos. Esta clase está diseñada para usarse solo en los raros casos en los que se requiere semántica de igualdad de referencias.

edición: Véase el comentario de Joachim Sauer a continuación, es muy fácil hacer una Set basado en un cierto Map. Que había necesidad de hacer algo como esto:

Set<E> mySet = Collections.newSetFromMap(new IdentityHashMap<E, Boolean>()); 
+0

...excepto que una interfaz 'Map' es completamente diferente de una interfaz' Set'. –

+3

No realmente, un conjunto es solo un mapa donde se ignoran los valores. Podrías escribir fácilmente un contenedor para que se vea más como un 'conjunto' si no quieres tratarlo todo el tiempo en tu aplicación. – Jesper

+2

+1 - Debería ser fácil implementar un conjunto basado en una implementación de mapa. Así es como se implementa HashSet ... –

1

Puede extender HashSet (o en realidad - AbstractSet), y una copia de la IdentityHashMap que utiliza System.identityHashCode(object) en lugar de obj.hashCode().

Usted puede simplemente googlear para IdentityHashSet, ya hay algunas implementaciones. O use Collections.newSetFromMap(..) según lo sugerido por Joachim Sauer.

Esto, por supuesto, debe hacerse solo si no está "en posesión" de las clases de sus objetos. De lo contrario, simplemente arregle su hashCode()

+0

Parece que sería más fácil anular 'hashCode()' que extender 'HashSet'. – danben

+0

si los objetos no están en su "posesión" – Bozho

+0

Derecha - suena como si estuvieran pero podría estar equivocado. – danben

3

Se puede envolver los objetos en una clase de contenedor que luego podría aplicar hashcode y equals basa simplemente en la identidad del objeto.

+1

+1 - esto será factible cuando no pueda arreglar los métodos, y extender la clase existente no es una opción. –

+1

Y si eres demasiado flojo para escribir tu propia clase contenedora, solo usa un 1-elemento 'Objeto []'. Feo, pero funciona. – polygenelubricants

+1

@polygenelubricantes: ¡Inteligente! Eso no se me había ocurrido. –

Cuestiones relacionadas