Colecciones Java – hashCode() y equals() – ¿Cómo anular el método equals() y hashcode() en Java?
Publicado: 2018-08-08
equals() y hashCode() en Java son dos métodos fundamentales que se declaran en la clase Object y en la biblioteca Java central o parcial.
Si tiene alguna de las siguientes inquietudes en Java, entonces está en el lugar correcto.
- Prácticas de Java -> Implementando iguales
- override – Anulando equals y hashCode en Java
- Cómo anular el método equals () en Java
- Cómo anular el método hashCode () en Java
- Cómo anular los métodos equals y hashCode en Java
- Cómo y por qué anular el método equals en Java
- ¿Por qué siempre anular hashcode () si anula equals ()?
Echemos un vistazo a un ejemplo simple para comprender primero la Igualdad de Reference Equality Logical Equality . El operador de igualdad (==) compara las referencias (direcciones en la memoria) de las dos cadenas como dos números diferentes; esto se conoce como Reference equality .
Logical equality compara los datos de los objetos en lugar del valor de las referencias.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com . crunchify . tutorials ; /** * @author Crunchify.com */ public class CrunchifyLogicalVsReferenceEqality { public static void main ( String [ ] args ) { String strA = new String ( "eBay" ) ; String strB = new String ( "eBay" ) ; String strC = new String ( "Paypal" ) ; // Create a String reference and assign an existing String's reference to it // so that both references point to the same String object in memory. String strD = strA ; // Print out the results of various equality checks // Reference Equality System . out . println ( "Reference Equality Result:" ) ; System . out . println ( strA == strB ) ; System . out . println ( strA == strC ) ; System . out . println ( strA == strD ) ; // Logical Equality System . out . println ( "\nLogical Equality Result:" ) ; System . out . println ( strA . equals ( strB ) ) ; System . out . println ( strA . equals ( strC ) ) ; System . out . println ( strA . equals ( strD ) ) ; } } |
Producción:
|
1 2 3 4 5 6 7 8 9 |
Reference Equality Result : false false true Logical Equality Result : true false true |
hashCode y equals están estrechamente relacionados:
- si anula equals , debe anular hashCode .
- hashCode debe generar valores iguales para objetos iguales.
- equals y hashCode deben depender del
same set of significant fields. Debe utilizar el mismo conjunto de campos en ambos métodos. No está obligado a utilizar todos los campos. Por ejemplo, es muy probable que un campo calculado que depende de otros se omita deequalsyhashCode.
Al implementar equals , los campos se comparan de manera diferente, según su tipo:
- campos de objetos, incluidas las colecciones: use iguales
- Enumeraciones con seguridad de tipo: utilice igual o == (equivale a lo mismo, en este caso)
- campos de objetos posiblemente nulos: use tanto == como iguales
- campos de matriz: use
Arrays.equals - campos primitivos que no sean float o double : use ==
-
float: convertir a int usandoFloat.floatToIntBits ,luego use == -
double: convertir a largo usandoDouble.doubleToLongBits, luego usar ==
Implementando código hash :
- si una clase anula equals , debe anular hashCode
- cuando ambos se reemplazan, equals y hashCode deben usar el mismo conjunto de campos
- si dos objetos son iguales, entonces sus valores hashCode también deben ser iguales
- si el objeto es inmutable, entonces hashCode es un candidato para el almacenamiento en caché y la inicialización diferida
Es un error popular pensar que hashCode proporciona un identificador único para un objeto. No es asi.
Por contrato general, el método equals() en Java debe ser reflexivo, simétrico, transitivo, consistente y cualquier referencia no nula debe devolver falso. En otras palabras, para valores arbitrarios de a, b y c, siempre deben pasar las siguientes pruebas:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/ reflexive property assertTrue ( a . equals ( a ) ) ; // symmetric property assertTrue ( a . equals ( b ) == b . equals ( a ) ) ; // transitive property if ( a . equals ( b ) && b.equals(c) ) { assertTrue( a.equals(c) ); } // consistency property assertTrue ( a . equals ( b ) == a . equals ( b ) ) ; // non-null property assertFalse ( a . equals ( null ) ) ; |
Para la mejor práctica, use los pasos a continuación para implementar su método equals():
- Use esto == eso para verificar la igualdad de referencia
- Use
instanceofpara probar el tipo de argumento correcto - Transmita el argumento al tipo correcto
- Compara campos significativos para la igualdad
Aquí hay un ejemplo completo.
CrunchifyImplementEqualsHashCode.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
package crunchify . com . tutorials ; /** * * @author Crunchify.com * How to Override equals() method in Java? * How to Override hasCode() method in Java? * version:1.2 * */ public class CrunchifyImplementEqualsHashCode { public static void main ( String [ ] args ) { CrunchifyImplementEqualsHashCode crunchifyTest = new CrunchifyImplementEqualsHashCode ( ) ; Crunchify one = new Crunchify ( 1 ) ; Crunchify two = new Crunchify ( 1 ) ; crunchifyTest . test1 ( one , two ) ; Crunchify three = new Crunchify ( 1 ) ; Crunchify four = new Crunchify ( 2 ) ; crunchifyTest . test2 ( three , four ) ; } public void test1 ( Crunchify one , Crunchify two ) { if ( one . equals ( two ) ) { System . out . println ( "Test1: One and Two are equal" ) ; } else { System . out . println ( "Test1: One and Two are not equal" ) ; } } public void test2 ( Crunchify three , Crunchify four ) { if ( three . equals ( four ) ) { System . out . println ( "Test2: Three and Four are equal" ) ; } else { System . out . println ( "Test2: Three and Four are not equal" ) ; } } } class Crunchify { private int value ; Crunchify ( int val ) { value = val ; } public int getValue ( ) { return value ; } // The method does override or implement a method declared in a supertype. @Override public boolean equals ( Object o ) { // null check if ( o == null ) { return false ; } // this instance check if ( this == o ) { return true ; } // instanceof Check and actual value check if ( ( o instanceof Crunchify ) && (((Crunchify) o).getValue() == this.value)) { return true; } else { return false ; } } @Override public int hashCode ( ) { int result = 0 ; result = ( int ) ( value / 11 ) ; return result ; } } |
Salida de la consola de Eclipse:
|
1 2 |
Test1 : One and Two are equal Test2 : Three and Four are not equal |
