Ayer me han preguntado en twitter si podría explicar la diferencia de Java == vs equals . En vez de responder por twitter lo voy a hacer directamente en el blog ya que me ha parecido una pregunta interesante. Supongamos que tenemos el siguiente bloque de código:
Ayer me han preguntado en twitter si podría explicar la diferencia de Java == vs equals . En vez de responder por twitter lo voy a hacer directamente en el blog ya que me ha parecido una pregunta interesante. Supongamos que tenemos el siguiente bloque de código:
package com.arquitecturajava; public class Principal3 { public static void main(String args[]) { int a=8; int b=5; int c=8; System.out.println(a==b); System.out.println(a==c); } }
En este caso estamos comparando tipos básicos los cuales se almacenaran en el stack o pila.
Compararlos es sencillo ya que estamos comparando valores por lo tanto a==c devolverá true. Otra cosa muy distinta ocurre si lo que nos creamos son objetos. Vamos a ver un ejemplo partiendo de la clase Persona.
package com.arquitecturajava; public class Persona { private String nombre; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Persona(String nombre) { super(); this.nombre = nombre; } }
Una vez creada la clase vamos a crear dos objetos:
package com.arquitecturajava; public class Principal4 { public static void main(String[] args) { Persona p= new Persona("cecilio"); Persona p1= new Persona("cecilio"); System.out.println(p==p1); } }
El resultado de comprar p y p1 devolverá false algo que a mucha gente le sorprende en un primer momento. Esto se debe a que he construido dos objetos y las variables p y p1 definen dos direcciones de memoria diferentes donde estos objetos están ubicados (heap). Así pues en el stack o pila de invocación entremos algo como lo siguiente.
Así pues es lógico que si comparamos p y p1 nos devuelva false ya que apuntamos a dos objetos diferentes. ¿Cómo podemos asegurarnos que p==p1 devuelve true?. Muy sencillo podemos crear un único objeto y hacer que dos variables o punteros apunten a él.
package com.arquitecturajava; public class Principal5 { public static void main(String[] args) { Persona p= new Persona("cecilio"); Persona p1=p; System.out.println(p==p1); } }
De esta manera como los dos punteros apuntan a la misma dirección de memoria.
El resultado del programa será true.
El método equals y hashCode
Mientras que es muy habitual usar el operador == para comparar tipos básicos no es tan habitual usarlo a la hora de comparar objetos ya que no tiene sentido a nivel de reglas de negocio. Por ejemplo en este caso a nivel de negocio consideraremos dos objetos iguales si tienen el mismo nombre. Por lo tanto deberemos sobreescribir el método equals y hashcode de la clase Persona y hacer que dos objetos Persona sean iguales si su nombre coincide :
package com.arquitecturajava; public class Persona { private String nombre; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Persona(String nombre) { super(); this.nombre = nombre; } @Override public int hashCode() { return nombre.hashCode(); } @Override public boolean equals(Object obj) { Persona p= (Persona)obj; return p.getNombre().equals(this.getNombre()); } }
Acabamos de sobreescribir los métodos (de forma simplificada) . Ahora podemos usar el método equals para comparar los siguientes objetos y nos devolverá true.
package com.arquitecturajava; public class Principal4 { public static void main(String[] args) { Persona p= new Persona("cecilio"); Persona p1= new Persona("cecilio"); System.out.println(p.equals(p1)); } }
Aunque tenemos dos variables que apuntan a objetos distintos ambos se consideran iguales a nivel semántico o de reglas de negocio que es lo que importa.
Existen clases que tienen el método equals ya sobrecargado por defecto. Un ejemplo clásico es la clase String. Dos cadenas son iguales si su texto es idéntico.
Muchas gracias Cecilio, ha sido de mucha ayuda!
de nada 🙂
Excelente explicacion, muchas gracias !!!!!
gracias 🙂
Hola Cecilio, entiendo lo de valor y referencia. me podrías explicar que pasa aqui
Integer a = 150;
Integer b = 150;
System.out.println(a == b); //false
Integer a = 120;
Integer b = 120;
System.out.println(a == b); //true
Voy a tener que escribir un artículo 🙂 , es un tema un poco peculiar de optimizaciones. Pero me parece interesante a ver si esta semana lo cubro
Intenger es una clase, int es un tipo primitivo por lo tanto se da lo que explica Cecilio, a es distinto de b, en el heap son dos objetos distintos, que tienen el valor un atributo igual (150)
Hasta ahora estoy viendo este articulo. Pero ¿por qué motivo sucede eso? ¿por qué al cambiar los valores parecieran que estos estuvieran ligados a su resultado (true o false)?
Hola cecilio, si entendí esos ejemplos pero aun me confunde este resultado:
int a = 5;
Integer b = new Integer(5);
System.out.println(a == b);// true.
¿Porque?
Es un tema de outboxing , que se encarga de convertir el tipo integer a tipo básico . A ver si escribo sobre ello 🙂
[…] Otros artículos relacionados: Java this vs super() , Java equals vs == […]
[…] trabajamos con Java tenemos que comparar objetos y tipos básicos entre ellos. Si recordamos de otro artículo anterior , para comparar tipos básicos usamos el operador == que es el operador de comparación . Por […]
Buenas tardes Cecilio, buen trabajo, solo me queda una duda, por lo que he entendido el == compara si las referencias o variables apuntan o no al mismo objeto en memoria, y para mi String es del tipo objeto. entonces ¿por que ? String valor1=”hola”; String valor2=”hola”; if(valor1==valor2)// resulta ser verdadero, para mi debería darme falso if(valor1.equals(valor2))// acá también da verdadero ,pero acá esta bien porque dijiste que el método equals esta sobreescrito ,lo que hace que compare que dos textos sea iguales o no. El jdk que estoy usando es la versión 8 Saludos y gracias de ante mano… Read more »
Es un caso particular, se trata de una situación en el que los Strings entran en un pool y se comparten , escribiré algo sobre el tema.
Te agradecería, a parte explicas muy bien,saludos y gracias.
Acabo de escribir un artículo ya que me parecía un tema muy interesante 😉 , gracias por la idea
Cecilio Álvarez Caules buenas tardes,acabo de leer el artículo, muy bueno, ya tengo claro el == y el equals(…), el String rompía con los conceptos y el entendimiento,pero ahora que leí el artículo sobre Java String Pool todo mejor, solo que ahora me presentaste un nuevo concepto que no lo tenia presente Java Flyweight pattern y rendimiento,espero entenderlo. Gracias por responder a mi pregunta.
Buenas tardes Cecillio. Tengo una pregunta, para ti cual seria la diferencia entre equals y hashCode entonces? gracias y saludos
mira este otro artículo
Excelente. No se puede explicar de una forma más sencilla. Saludos! 🙂
gracias 🙂
Me ha encantado encontrarme con esta explicación. Sencilla y fácil de leer. Hace poco hice una prueba donde precisamente una de las preguntas estaba relacionada. Obviamente llevo mucho en esto y no tuvo dificultad pero hay mucha gente a la que aún le cuesta llegar a estos conceptos.
Un saludo y buen trabajo.
Gracias 🙂
Genial! que explicación más limpia…
Por cierto siempre me he preguntado qué programa usas para hacer esas gráficas.
Saludos desde colombia
gracias 🙂 . El omnigrafle para mac