java - ¿Por qué el método equals() cuando tenemos== operador?
referenceequals (8)
"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
}
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo comparo cadenas en Java? 23 respuestas
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?
== 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;
}
}
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;
}
}
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.
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.
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)
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.