El método igual en la clase de objeto se usa para detectar si un objeto es igual a otro objeto. En la clase de objetos, este método determina si dos objetos tienen la misma referencia. Si los dos objetos tienen la misma referencia, deben ser iguales. Desde este punto de vista, es razonable usarlo como la operación predeterminada. Sin embargo, para la mayoría de las clases, este juicio no tiene sentido. Por ejemplo, no tiene sentido comparar si dos impresiones impresas son iguales de esta manera. Sin embargo, a menudo es necesario detectar la igualdad de los estados de dos objetos. Si los estados de los dos objetos son iguales, los dos objetos se consideran iguales. Por lo tanto, en general, las comparaciones iguales deben reescribirse en clases personalizadas.
Aquí hay algunas sugerencias para escribir un método perfecto () igual ():
(1) El parámetro explícito se denomina OtherObject, y debe convertirse en una variable llamada otra posterior
(2) Detectar si este y otro Object se refieren al mismo objeto:
if (this == OtherObject) return True;
Esta declaración es solo una optimización. De hecho, esta es una forma que a menudo se adopta. Porque calcular esta ecuación es mucho menos costoso que comparar los campos en una clase uno por uno.
(3) Verifique si OtherObject es nulo y, si es nulo, devuelve falso. Esta prueba es necesaria.
if (otherObject == null) return false;
(4) Compare si este y otro objeto pertenecen a la misma clase. Si la semántica de igual cambio en cada subclase, use getClass () para detectarlo, lo que se toma como la clase de destino
if (getClass ()! = OtherObject.getClass ()) return false;
Si todas las subclases tienen la misma semántica, use instancia de detección
if (! (otherObject instancia de classname)) return false;
(5) Convierta OtroBject a una variable del tipo correspondiente:
Classname otro = (className) OtroBject;
(6) Ahora comience a comparar todos los dominios que deben compararse. Use == para comparar el dominio de tipo básico y usar iguales para comparar el dominio del objeto. Devolver verdadero si todos los campos coinciden, de lo contrario regresan falso;
Field de retorno1 == OTRO.FIELD1 && Field2.Equals (OTRO.FIELD2)
Si es igual a redefinido en una subclase, debe incluir la llamada super.equals (otros). Si la detección falla, es imposible ser igual. Si los dominios en la superclase son iguales, compare los dominios de instancia en la subclase.
Para los campos de tipo matriz, puede usar las matrices estáticas. Método equivalente para detectar si los elementos correspondientes son iguales.
Echemos un vistazo a algunos ejemplos de comparación de cuerdas:
Cadena a = "ABC"; Cadena B = "ABC"; Cadena C = nueva cadena ("ABC"); Cadena d = nueva cadena ("ABC"); System.out.println (a == b); // Verdadero porque las constantes de cadena se comparten en Java, solo hay una copia System.out.println (a == c); // falsos a y c pertenecen a 2 objetos diferentes system.out.println (a.equals (c)); // Verdadero Dado que el método igual del objeto de cadena compara los valores en el objeto, devuelve verdadero. (Diferente del método igual del objeto) System.out.println (c == d); // falsos Aunque los valores en los objetos son los mismos, pertenecen a 2 objetos diferentes, por lo que no son iguales System.out.println (C.Equals (d)); // verdaderoEn pocas palabras, al comparar las constantes de cadena, es el mismo que el resultado devuelto por igual. Cuando desee comparar el valor del objeto de cadena, use iguales.
Vea un ejemplo de uso de iguales:
paquete capítulo 05.Equalstest; import java.util.*; clase pública igual a {public static void main (string [] args) {empleado alice1 = nuevo empleado ("Alice Adams", 75000, 1987, 12, 15); Empleado Alice2 = Alice1; // Referencia al mismo objeto Empleado Alice3 = nuevo empleado ("Alice Adams", 75000, 1987, 12, 15); Empleado Bob = nuevo empleado ("Bob Brandson", 50000, 1989, 10, 1); System.out.println ("Alice1 == Alice2:" + (Alice1 == Alice2)); System.out.println ("Alice1 == Alice3:" + (Alice1 == Alice3)); System.out.println ("Alice1.Equals (Alice3):" + (Alice1.Equals (Alice3))); System.out.println ("Alice1.equals (Bob):" + (Alice1.Equals (Bob))); System.out.println (bob.ToString ()); }} empleado de clase {empleado público (cadena n, doble s, int año, int mes, int day) {name = n; salario = s; Calendario Gregoriancalendar = nuevo Gregoriancalendar (año, mes, día); Hireday = calendar.gettime (); } public String getName () {nombre de retorno; } public Double GetSalary () {Salario de retorno; } Fecha pública gethireday () {return Hireday; } public void eleva (doble bypercentcent) {double raise = salary * bypercentcent / 100; salario += elevar; } @Override public boolean iguales (objeto OtroBject) {// Una prueba rápida para ver si los objetos están identificados si (this == OtherObject) return true; // debe devolver falso si el parámetro explícito es nulo if (otherObject == null) return false; // Si el clasificado no coincide, no pueden ser igual si (getClass ()! = OtherObject.getClass ()) return false; // Ahora sabemos que OtherObject es un empleado no nulo de empleado Otro = (Empleado) OtroBject; // Prueba si los campos Hava identificaron los valores de retorno name.equals (other.name) && salary == otros.salary && hireday.equals (otro.hireday); } @Override public int hashcode () {return 7 * name.hashCode () + 11 * new Double (salario) .hashCode () + 13 * Hireday.hashCode (); } @Override public string toString () {return getClass (). GetName () + "[name =" + name + ", salary =" + salario + ", contrateday =" + hireday + "]"; } nombre de cadena privada; salario doble privado; fecha privada contratada; } El gerente de clases extiende al empleado {Manager público (String n, Double S, int Year, Int Month, int Day) {super (n, s, año, mes, día); Bouns = 0; } @Override public Double GetSalary () {Double BasSalary = super.getSalary (); Basario de retorno + Bouns; } public void setBouns (doble b) {bouns = b; } @Override public boolean iguales (Object OthersObject) {if (! Super.equals (OtroBject)) return false; Administrador OTRO = (Manager) OtroBject; // Super Equals verificó que este y otro pertenecen a los mismos bouns de retorno de clase == Otros.Bouns; } @Override public int hashcode () {return super.hashcode () + 17 * new double (bouns) .hashcode (); } @Override public string toString () {return super.ToString () + "[bouns =" + bouns + "]"; } Bouns dobles privados; } Profundizar y divídalo en 2 categorías de acuerdo con "si la clase anula el método igual ()".
(1) Si una clase no anula el método igual (), cuando compara los dos objetos a través de igual (), en realidad está comparando si los dos objetos son el mismo objeto. En este momento, es equivalente a comparar estos dos objetos por "==".
(2) Podemos anular el método igual () de la clase para dejar que igual () compare si dos objetos son iguales de otras maneras. La práctica habitual es: si el contenido de dos objetos es igual, el método igual () devuelve verdadero; De lo contrario, devuelve Fasle.
A continuación, damos un ejemplo para explicar las dos situaciones anteriores.
1. El caso de "no anular el método igual ()"
El código es el siguiente (Equalstest1.java):
import java.util.*; import java.lang.comparable;/*** @Desc iguals () programa de prueba. */public class EqualStest1 {public static void main (string [] args) {// Crea 2 nuevos objetos de persona con el mismo contenido, // usa iguales para comparar si son la persona igual p1 = nueva persona ("eee", 100); Persona p2 = nueva persona ("eee", 100); System.out.printf ("%s/n", p1.equals (p2)); } /*** @Desc Clase Person. */ persona de clase estática privada {int Age; Nombre de cadena; Persona pública (nombre de cadena, int Age) {this.name = name; this.age = edad; } public String toString () {Nombre de retorno + " -" + edad; }}} Resultados de ejecución:
Copie el código de la siguiente manera: FALSO
Análisis de resultados Usamos P1.Equals (P2) para "comparar si P1 y P2 son iguales". De hecho, el método igual () de object.java se llama, es decir, el (p1 == p2) llamado. Es comparar "si P1 y P2 son el mismo objeto".
Según las definiciones de P1 y P2, podemos ver que aunque su contenido es el mismo, ¡son dos objetos diferentes! Por lo tanto, el resultado de retorno es falso.
2. La situación de "sobrescribir al igual () método"
Modificamos el iguales1.java anterior: anular el método igual ().
El código es el siguiente (igual.test2.java):
import java.util.*; import java.lang.comparable;/*** @Desc iguals () programa de prueba. */public class EqualStest2 {public static void main (string [] args) {// Crea 2 nuevos objetos de persona con el mismo contenido, // usa iguales para comparar si son igual persona p1 = nueva persona ("eee", 100); Persona p2 = nueva persona ("eee", 100); System.out.printf ("%s/n", p1.equals (p2)); } /*** @Desc Clase Person. */ persona de clase estática privada {int Age; Nombre de cadena; Persona pública (nombre de cadena, int Age) {this.name = name; this.age = edad; } public String toString () {Nombre de retorno + " -" + edad; } / *** @Desc anular el método igualizante* / @Override public boolean iguales (object obj) {if (obj == null) {return false; } // Si es el mismo objeto, return true, de lo contrario, return false if (this == obj) {return true; } // juzga si el tipo es el mismo if (this.getClass ()! = Obj.getClass ()) {return false; } Persona persona = (persona) obj; return name.equals (persona.name) && age == Person.age; }}} Resultados de ejecución:
Copie el código de la siguiente manera: Verdadero
Análisis de resultados:
Anulamos la función Equals () de la persona en Ecalstest2.Java: cuando el nombre y la edad de los objetos de dos personas son iguales, devuelve verdadero.
Por lo tanto, el resultado de ejecución devuelve verdadero.
Dicho esto, hablemos de los requisitos de Java para igual (). Hay los siguientes puntos:
Symmetry: si x.equals (y) devuelve "verdadero", entonces Y.equals (x) también debería devolver "verdadero".
Reflectividad: X.Equals (x) debe devolver "verdadero".
Analogía: si X.Equals (y) devuelve "verdadero" e y.equals (z) devuelve "verdadero", entonces z.equals (x) también debería devolver "verdadero".
Consistencia: Si X.Equals (y) devuelve "verdadero", siempre que el contenido de X e Y permanezca sin cambios, no importa cuántas veces repita X.Equals (y), el retorno será "verdadero".
No vacío, x.equals (nulo), siempre devuelve "falso"; X.Equals (objetos de diferentes tipos y x) siempre devuelve "falso".
Ahora, revisemos el papel de igual (): determine si dos objetos son iguales. Cuando reescribimos igual (), ¡es imposible cambiar su función!
¿Cuál es la diferencia entre igual () y ==?
==: Su función es determinar si las direcciones de dos objetos son iguales. Es decir, determine si los dos objetos son el mismo objeto.
Equals (): Su función es determinar si dos objetos son iguales. Sin embargo, generalmente tiene dos condiciones de uso (se ha descrito en detalle en la parte anterior 1):
Caso 1, la clase no anula el método igual (). Luego, al comparar dos objetos de esta clase a través de igual (), es equivalente a comparar estos dos objetos por "==".
Caso 2, la clase anula el método igual (). En general, anulamos el método igual () para que el contenido de dos objetos sea igual; Si su contenido es igual, devuelve verdadero (es decir, los dos objetos se consideran iguales).
A continuación, compare sus diferencias con ejemplos.
El código es el siguiente:
import java.util.*; import java.lang.comparable;/*** @Desc iguals () programa de prueba. */public class EqualStest3 {public static void main (string [] args) {// Crea 2 nuevos objetos de persona con el mismo contenido, // usa iguales para comparar si son igual persona p1 = nueva persona ("eee", 100); Persona p2 = nueva persona ("eee", 100); System.out.printf ("P1.Equals (P2): %S/N", P1.Equals (P2)); System.out.printf ("P1 == P2: %S/N", P1 == P2); } /*** @Desc Clase Person. */ persona de clase estática privada {int Age; Nombre de cadena; Persona pública (nombre de cadena, int Age) {this.name = name; this.age = edad; } public String toString () {Nombre de retorno + " -" + edad; } / *** @Desc anular el método igualizante* / @Override public boolean iguales (object obj) {if (obj == null) {return false; } // Si es el mismo objeto, return true, de lo contrario, return false if (this == obj) {return true; } // juzga si el tipo es el mismo if (this.getClass ()! = Obj.getClass ()) {return false; } Persona persona = (persona) obj; return name.equals (persona.name) && age == Person.age; }}} Resultados de ejecución:
P1.Equals (P2): TRueP1 == P2: Falso
Análisis de resultados:
En igual.pelp.java:
(1) P1. Equals (P2)
Esto es para determinar si el contenido de P1 y P2 son iguales. Debido a que la persona anula el método igual (), y esto es igual () se usa para determinar si el contenido de P1 y P2 son iguales, exactamente el contenido de P1 y P2 son iguales; Por lo tanto, devuelve verdadero.
(2) P1 == P2
Esto es para determinar si P1 y P2 son el mismo objeto. Dado que son dos objetos de persona nueva cada uno; Por lo tanto, devuelve falso.