¿Por qué el método equals () cuando tenemos == operador?

Cuando veo la implementación del método equals() no hace más que lo mismo que what == does. Entonces mi pregunta es ¿cuál fue la necesidad de tener esto como método separado cuando tenemos el operador == que hace el mismo trabajo?

No puede sobrecargar el operador == , pero puede anular equals(Object) si desea que se comporte de manera diferente al operador == , es decir, no compare referencias pero compare realmente los objetos (por ejemplo, utilizando todos o algunos de sus campos).

Además, si anula equals(Object) , también eche un vistazo a hashCode() . Estos dos métodos deben ser compatibles (es decir, dos objetos que son iguales de equals(Object) a equals(Object) deben tener el mismo hashCode() ), de lo contrario se producirán todo tipo de errores extraños (por ejemplo, al agregar los objetos a un conjunto o mapa) .

== compara referencias de objetos, y pregunta si las dos referencias son las mismas.

equals() compara el contenido del objeto y pregunta si los objetos representan el mismo concepto.

En el caso de las primitivas , el operador == verifica si dos valores son iguales.
Si no son primitivos, verifica si se trata de dos punteros (o referencias ) que apuntan a la misma instancia de un objeto.

El método equals() realiza una comprobación personalizada, que está en Object comprobando la referencia, usando == . Pero en otras clases, a veces equals() se anula (no sé si este es un participio pasado correcto) . equals() tiene que verificar el contenido .

Así por ejemplo:

 int i0 = 34; int i1 = 34; int i2 = 35; // results i0 == i1: true i1 == i0: true i2 == i0: false 

Pero si tenemos no primitivos

 String str0 = new String("Hello man!"); String str1 = new String("Hello man!"); String str2 = new String("!nam olleH"); String str2copy = str2; // Results str0 == str1: false // Pointer to two different object, so == will give false str1 == str2: false // Idem str2 == str2copy: true // So this are two pointers to the same object str0.equals(str1): true // This are not the same objects, but they are equal str1 == str1: true // Again: two times a pointer to the same object 

Entonces, ¿ str0.equals(str1) qué str0.equals(str1) devuelve true ? Porque la clase String tiene una anulación de equals() . Y en ese método no verifica si son iguales al hacer return this == obj; Pero en ese método, hay una verificación completa. No sé qué método usan para comparar las dos cadenas, pero aquí hay dos formas posibles:

  • Generar a partir de las dos cadenas un código hash y verificar si son iguales ( int == int )
  • Verificando carácter por personaje si son iguales.

Así que espero que esto esté claro ahora.

Hay una diferencia muy importante entre los dos.

“==” compara instancias de objeto. La implementación predeterminada equals () hace esto, también. Ejecute y analice la siguiente muestra de código:

 public class Person{ String name; public Person(String name){ this.name = name; } //overriding equals public boolean equals( Object obj ) { if( this == obj ) return true; if( obj == null ) return false; if( getClass() != obj.getClass() ) return false; Person other = (Person) obj; if( name == null ) { if( other.name != null ) return false; } else if( !name.equals( other.name ) ) return false; return true; } } ... ... Person john1 = new Person("John"); Person john2 = new Person("John"); System.out.println("john1 == john2:" + (john1 == john2)); System.out.println("john1.equals(john2):" + john1.equals(john2)); 

Como puede ver, “==” devolverá falso (los objetos son dos instancias diferentes de Person), mientras que equals devolverá true (porque definimos que 2 Persons son iguales cuando tienen el mismo nombre)

== operador se usa para comparar referencias.
El método equals () se define sobre la definición del objeto.

 Dog d =new Dog(); Collar c =new Collar("Red"); d.setCollar(c); Dog d2=new Dog(); Collar c2=new Collar("Red"); d2.setCollar(c2); d2.getCollar() ==d.getCollar() 

devolvería falso indicando que los dos perros tienen dos objetos de cuello diferentes (artículos). No comparten el mismo collar .

 d2.getCollar().equals(d.getCollar()) 

devuelve true si el Collar se define como [Collar son iguales si el color del Cuello es el mismo] los dos perros tienen el mismo collar de color.

  class Collar{ String color=""; public Collar(String p0){ this.color=p0; } boolean equals(Object c){ Collar other=(Collar)c; return this.color.equals(other.getColor()); } public String getColor(){ return this.color; } } 

Eso se hace para que esto sea posible:

 String s1 = new String("foo"); String s2 = new String("foo"); System.out.println(s1 == s2); // false?! Different references! System.out.println(s1.equals(s2)); // true 

Si comprueba el origen de String#equals() , verá que ha anulado el Object#equals() adecuadamente para comparar la matriz de caracteres interna (el valor real ). Muchas otras clases tienen este método anulado también.

“string” == “string” devolverá false “string” .equals (“string”) devolverá true

Con o1 == o2 se compara que el objeto 1 es el mismo objeto que o2 (por referencia)

Con o1.equals (o2), dependiendo del objeto, el método igual es anulado y no implementado con algo como “return o1 == o2”

Por ejemplo, puede crear 2 instancias de conjunto. Estos 2 objetos configurados son 2 objetos diferentes, puede agregar elementos diferentes en cualquiera de ellos. set1 == set2 siempre devolverá false pero set1.equals (set2) eventualmente devolverá true si el set2 contiene exactamente los mismos elementos que set1 … y porque el método equals es anulado en la clase Set …

La implementación igual para Set es:

  public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Set s = (Set) o; if (s.size() != c.size()) return false; return containsAll(s); // Invokes safe containsAll() above } 

En Java, el operador (==) opera en los datos de dos variables si los operandos son de tipos de datos primitivos. Pero si los operandos son objetos, java los compara usando referencias porque no tiene manera de averiguar para comparar en qué campo o campos del objeto.

Entonces solo hay una forma de comparar en base a los campos definidos por el usuario y que se define en el objeto anulando los métodos equals (), ya que el operador igual (==) no puede anularse en java ya que java no admite anulación del operador.

Como ejemplo, si desea comparar Empleado sobre la base de su nombre, debe definir su lógica anulando el método equals en la clase Employee de la siguiente manera:

 public class Employee { private Integer id; private String name; @Override public boolean equals(Object obj) { Employee other = (Employee) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }