2012-08-26 15 views
17

Object en Java tiene hashCode método, sin embargo, sólo se utiliza en contenedores asociativos como HashSet o HashMap. ¿Por qué fue diseñado así? Hashable interfaz que tiene hashCode método parece una solución mucho más elegante.¿Por qué no hay interfaz Hashable en Java

+0

¿Por qué necesita una interfaz especial cuando puede anularla en todas partes y Object es por defecto super clase de todas? – kosa

+2

@Namban La pregunta es más de "¿Por qué cada Objeto tiene un método hashCode(), cuando solo lo usan unas pocas clases de colección java.util. *?" es decir, por qué no está, por ejemplo, una interfaz ObjectHash, al igual que hay una interfaz comparable, etc. – nos

+1

Esto es más un tema de discusión que una pregunta, por lo que no es realmente adecuado para SO. – Keppil

Respuesta

6

El argumento principal me parece que existe un valor hashCode predeterminado bien definido que se puede calcular para cualquier objeto Java, junto con un equals igualmente bien definido. Simplemente no hay una buena razón para retener esta función de todos los objetos, y por supuesto hay muchas razones no para retenerla. Por lo tanto, es una obviedad en mi libro.

+0

No creo que indique que debería haber un procedimiento general para obtener 'hashCode'; él está diciendo que 'hashCode' debería formar parte de alguna interfaz' Hashable' y no en 'Object'. – oldrinb

+0

@veer sí, exactamente eso – karlicoss

+0

@veer OK, ahora veo. Leí mal. Pero aún así, es solo una razón ligeramente diferente entonces. –

0

Esta pregunta se reclama como un duplicado de otra que pregunta por qué no hay una interfaz que se comporte como Comparator (a diferencia de Comparable) pero para hash. .NET incluye una interfaz de este tipo, llamada IEqualityComparer, y parece que Java también podría hacerlo. Como es, si alguien quiere, p. tener una colección de Java que p. asigna cadenas a otros objetos de manera que no distinga entre mayúsculas y minúsculas (quizás sea el uso más común de IEqualityComparer), debe envolver las cadenas en objetos cuyos métodos hashCode y equals actúen en función de mayúsculas y minúsculas.

Sospecho que el gran problema es que, si bien una interfaz "equalityComparer" podría ser conveniente, en muchos casos, la prueba eficiente de una relación de equivalencia requeriría información de almacenamiento en caché. Por ejemplo, aunque una función de hashing de cadena que no distingue entre mayúsculas y minúsculas podría hacer una copia en mayúscula de la cadena transferida y llamar al hashCode sobre eso, sería difícil evitar que cada solicitud del código hash de una cadena en particular repita la conversión. a mayúsculas y el hash de ese valor en mayúscula. Por el contrario, un objeto de "cadena insensible a mayúsculas y minúsculas" podría incluir campos para una copia en mayúscula de la cadena, que solo tendría que generarse una vez para la instancia.

Un EqualityComparer podría lograr un rendimiento razonable si incluye algo así como un WeakHashMap<string,string> para convertir cadenas primas a mayúsculas-sólo cadenas, pero tal diseño sería bien requerir diferentes hilos de utilizar diferentes EqualityComparer casos a pesar de la falta de estado visible desde el exterior, o de lo contrario, se requiere un código de sincronización y bloqueo que elimine el rendimiento incluso en escenarios de subproceso único. Incidentalmente, un segundo problema que surge con las interfaces de estilo comparador es que un tipo de colección que utiliza un comparador suministrado externamente (si se compara por rango o igualdad) es que el comparador se convierte en parte del estado de la clase que lo usa. Si las tablas hash utilizan diferentes instancias de EqualityComparer, puede que no haya forma de saber que pueden considerarse equivalentes con seguridad, incluso si los dos comparadores se comportarían de forma idéntica en todas las circunstancias.

0

¿De qué sirve tener una interfaz que todos los objetos implementen de todos modos por inheritage? Como Object lo implementa y se supone que es hashable, debería tener implements Hashable en su declaración, y todas las demás clases lo heredarían porque son subclases de Object. Tener una interfaz Hashable simplemente establecería lo obvio.

+0

Bajo el mismo pensamiento podemos preguntar, ¿de qué sirve tener dos métodos que cada objeto tenga, pero que nunca haya usado? Y cuando finalmente se usan llamando solo a un método pero no al otro, el código de la persona que llama falla espectacularmente. Entonces, ¿qué justifica esta decisión de diseño? –

Cuestiones relacionadas