public class Equivalencia { public static void main(String[] args) { Integer n1 = new Integer(47); Integer n2 = new Integer(47); System.out.println("n1==n2: "+n1 == n2); System.out.println("n1!=n2: "+n1 != n2); String s1 = new String("Hola"); String s2 = new String("Hola"); System.out.println("s1==s2: "+s1 == s2); System.out.println("s1!=s2: "+s1 != s2); } }
Si lo ejecutamos el resultado es:
n1==n2: false n1!=n2: true s1==s2: false s1!=s2: true
Esto se debe a que los operadores == y != comparan referencias, no valores. La referencia de n1 está almacenada en un lugar de la memoria y la de n2 en otra, lo mismo para s1 y s2. Recuerda que cada vez que se crea un objeto con new se le asigna un espacio de memoria en el cúmulo.
Para comparar objetos, no tipos primitivos, tenemos el método equals(), que se puede utilizar siempre, ya que está incluido en la clase java.lang.Object que por defecto heredan todas las clases. Este método compara valores en lugar de referencias, modificamos un poco el ejemplo anterior y utilizamos equals():
public class Equivalencia2 { public static void main(String[] args) { Integer n1 = new Integer(47); Integer n2 = new Integer(47); System.out.println("n1.equals(n2): "+n1.equals(n2)); String s1 = new String("Hola"); String s2 = new String("Hola"); System.out.println("s1.equals(s2): "+s1.equals(s2)); } }
El resultado es:
n1.equals(n2): true s1.equals(s2): true
Sin embargo, fijémonos en los dos siguientes ejemplos:
class Value { int i; } public class Equivalencia3 { public static void main(String[] args) { Value v1 = new Value(); Value v2 = new Value(); v1.i = v2.i = 100; System.out.println("v1.i=v2.i=100"); System.out.println("v1.equals(v2): "+v1.equals(v2)); } }
El resultado es:
v1.i=v2.i=100 v1.equals(v2): false
El ejemplo siguiente es una variación del Ejercicio 6 del Tema 3. Este ejercicio lo he hecho de varias maneras.
class Dog2{ String name; String says; Dog2(String n,String s){ name=n; says=s; } public String nombre(){ return name; } public String says(){ return says; } } public class Ejer_6b{ public static void main(String args[]){ Dog2 dogSpot=new Dog2("Spot","Ruff"); Dog2 dogScruffy=new Dog2("Scruffy","Wurf"); Dog2 dogNuevo=new Dog2("Spot","Ruff"); System.out.println("Tengo dos perritos."); System.out.println("Uno se llama: "+dogSpot.nombre()+" y ladra diciendo: "+dogSpot.says()); System.out.println("El otro se llama: "+dogScruffy.nombre()+" y ladra diciendo: "+dogScruffy.says()); System.out.println("Paco tiene otro perrito y dice que es igual que Spot o que Scruffy, vamos a comprobarlo"); System.out.println("Si comparamos a Spot con el perro de Paco utilizando ==: "+(dogSpot==dogNuevo)); System.out.println("Si comparamos a Scruffy con el perro de Paco utilizando ==: "+(dogScruffy==dogNuevo)); System.out.println("Si comparamos a Spot con el perro de Paco utilizando equals: "+dogNuevo.equals(dogSpot)); System.out.println("Si comparamos a Scruffy con el perro de Paco utilizando equals: "+dogNuevo.equals(dogScruffy)); } }
Aquí el resultado es:
Tengo dos perritos. Uno se llama: Spot y ladra diciendo: Ruff El otro se llama: Scruffy y ladra diciendo: Wurf Paco tiene otro perrito y dice que es igual que Spot o que Scruffy, vamos a comprobarlo Si comparamos a Spot con el perro de Paco utilizando ==: false Si comparamos a Scruffy con el perro de Paco utilizando ==: false Si comparamos a Spot con el perro de Paco utilizando equals: false Si comparamos a Scruffy con el perro de Paco utilizando equals: false
En las clases creadas por nosotros, el método equals() se comporta comparando referencias, es decir, como el operador ==, por tanto, para comparar dos objetos y comprobar si son iguales o no, deberíamos sobreescribir el método equals() para que tenga este comportamiento, esto lo veremos más adelante.
Vamos a darle otra vuelta de tuerca:
public class Equivalencia4 { public static void main(String[] args) { Integer n1 = 47; Integer n2 = 47; Integer n3 = new Integer(47); System.out.println("n1==n2: "+(n1 == n2)); System.out.println("n1!=n2: "+(n1 != n2)); System.out.println("n1.equals(n2): "+n1.equals(n2)); System.out.println("n1==n3: "+(n1 == n3)); System.out.println("n1.equals(n3): "+n1.equals(n3)); String s1 = "Hola"; String s2 = "Hola"; System.out.println("s1==s2: "+(s1 == s2)); System.out.println("s1!=s2: "+(s1 != s2)); System.out.println("s1.equals(s2): "+s1.equals(s2)); } }
El resultado es:
n1==n2: true n1!=n2: false n1.equals(n2): true n1==n3: false n1.equals(n3): true s1==s2: true s1!=s2: false s1.equals(s2): true
Cuando creamos n1 y le damos el valor 47, este valor se guarda en memoria (en la pila). Al crear una nueva variable con valor 47, en lugar de almacenar este valor en memoria, como ya existe, n2 apuntará al valor 47 que está en la pila. Entonces tenemos n1 y n2 apuntando a 47. Lo mismo ocurriría con s1 y s2. Por este motivo, en este ejemplo, las comparaciones tienen el mismo comportamiento para == (referencias) y equals() (valores). Sin embargo, si damos un nuevo valor a n1, n2, s1 o s2, las variables ya no apuntarán al mismo valor y serán de este modo diferentes, tanto para == como para equals(). Si nos fijamos en la variable n3, se crea con new Integer(47), si la comparamos con n1 o n2 el resultado es el siguiente: con == el resultado sería false, ya que al crear un nuevo objeto con new, se le asigna un nuevo espacio de memoria (en el cúmulo), por tanto no apuntaría al valor 47 de la pila, sin embargo, con equals() el comportamiento es el esperado ya que se comparan los valores y estos son iguales. Para recordar dónde se almacena cada tipo de variable, puedes repasar el Tema 2, el apartado Los lugares de almacenamiento.
es muy poco aclaratorio lo que explicas, te complicas mucho la vida. por ejemplo no explicas que si comparas 2 strings, la comparacion es correcta porque la classe String tiene un mètodo equals, por tanto es logico que te de bien la comparacion de dos strings. en ningun momento enseñas como hacer correctamente el equals.
ResponderEliminaren parte encuentro bien que la gente explique lo que sabe, pero no estoy deacuerdo a que se lie a la gente con explicaciones incompletas y mal hechas
Hola:
EliminarNo sé exactamente por qué escribí este artículo, creo que fue por algún problema que me encontré con el operador "==" y escribí este artículo por si alguien se encontraba el mismo problema.
Cuando escribo un artículo, trato de documentarme al máximo y créeme, hasta que lo publico le doy mil vueltas, así que si piensas que mi explicación está incompleta o mal hecha, no ha sido por no informarme o no trabajar en lo que escribo.
Si crees que está incompleto o mal explicado, desde aquí te animo a que tú mismo/a hagas un artículo que explique todo mejor y yo me comprometo a publicártelo.
Un saludo.
No hagas caso, la envidia siempre lleva a ver errores donde no los hay, a mi me parecio bastante buena tu explicacion y con ejemplos sencillos. Saludos!
ResponderEliminarGracias.
EliminarYo acepto las críticas malas, ya que seguro que me hacen mejorar, lo que pasa es que para alguien que hace un blog de manera desinteresada, que "pierde" parte de su tiempo libre en escribir para los demás, le desaniman un poco estos comentarios, pero bueno, también las críticas negativas son necesarias, no todo va a ser bueno ¿no?
Un saludo y me alegro de que te sea útil el blog.
Me pareció bastante interesante :D
ResponderEliminarMuchas gracias, me alegro de que te haya sido útil.
EliminarUn saludo.
Excelente artículo, no hagas caso de los malos comentarios
ResponderEliminarMuchas gracias, la verdad es que os estoy muy agradecida. Me alegro mucho de que mi trabajo os ayude a entender mejor Java.
EliminarSaludos.
yo creo que quien comento desfaborablemente en primer lugar tiene razon y en segundo lugar tiene todo el derecho de emitir tal comentario, que no presenta tener mala voluntad sino contribuir con su real opinion ademas de haber sido concreto en lo tecnico y no personal como otros.
ResponderEliminarHola:
EliminarEstá claro que no hay ni que dejarse llevar por los comentarios buenos y aprender de los malos, ya que eso me permitirá mejorar.
Lo que tenéis que tener claro es que mejor o peor, escribo el blog tratando de ayudar a la gente y tratando de hacerlo lo mejor posible.
Los comentarios negativos sólo me servirán para mejorar y pienso que son necesarios.
Un saludo y gracias.
GRACIAS!
ResponderEliminarDe nada. Espero que te sea útil mi blog y te ayude a aprender.
EliminarSaludos.
El artículo es bueno ya que aporta una demostración lógica completa del comportamiento de los operadores == y equals. De hecho el artículo se titula: "Diferencias entre método equals() y operador ==". Cómo reimplementar el método equals correctamente debería ocupar otro artículo.
ResponderEliminarMi enhorabuena por el Blog.
Muchas gracias, me alegro mucho de que te haya servido de ayuda, ese es el objetivo del blog.
EliminarSaludos y suerte.
if (CBOListGasolina.getSelectedItem().equals("84 Octanos")) {
ResponderEliminarMostrar resultados - funciona
}
Pero si lo coloco dentro de un evento ItemStateChanged
private void CBOListGasolinaItemStateChanged(java.awt.event.ItemEvent evt) {
if (CBOListGasolina.getSelectedItem().equals("8d4 Octanos")) {
////No Funciona
**Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at gui.Ventana.CBOListGasolinaItemStateChanged***
}
por que funciona en un metodo y en otro no???
Hola:
EliminarFíjate que dentro del método CBOListGasolinaItemStateChanged has puesto equals("8d4 Octanos") en lugar de equals("84 Octanos"), quizá de ahí viene el error.
Un saludo.
Bien con el articulo, por la experiencia que tengo he tenido problemas con estos operadores ==, !=, y no siempre haces uso de los equals, por lo que hay q saber como utilizarlos.
ResponderEliminarHay que tener claro la diferencia entre equals y estos operadores.
EliminarMe alegro de que te haya gustado.
Saludos.
Sigo sin saber cuando usar equals y cuando usar ==...
ResponderEliminarTe recomiendo que te leas en el tema 3 el apartado: Comprobación de la equivalencia de objetos http://piensaenjavadesdecero.blogspot.com.es/2011/02/operadores_01.html a ver si te ayuda a aclararte.
Eliminarequals se utiliza con objetos y los operadores == y != con primitivas.
Saludos.
Hola, no entiendo por qué v1.i = v2.i = 100 y v1.equals(v2) es false si a ambos objetos se les asigna el mismo valor a i
ResponderEliminarHola:
EliminarRespondo a tu pregunta.
En las clases creadas por nosotros, el método equals() se comporta comparando referencias, es decir, como el operador ==, por tanto, para comparar dos objetos y comprobar si son iguales o no, deberíamos sobreescribir el método equals() para que tenga este comportamiento, eso lo veremos más adelante.
Espero haberte ayudado.
Un saludo y gracias.
Muy buena la info, si quieres de doy dominio y hosting.
ResponderEliminar"da te vid @ gmail . com"
Saludos
Este comentario ha sido eliminado por el autor.
ResponderEliminarBuenas! me parece una buena explicación y me gustaría dar mi opinión al respecto (espero no meter la pata jeje) :
ResponderEliminarEl operador == comprueba si los elementos a comparar tienen el mismo valor. En el caso de referencias a objetos, comprueba que las referencia sea la misma, es decir, que apunten a la misma zona de memoria (que viene a decir que apunten al mismo objeto).
Cuando tu creas una clase, deriva de la clase Object que cuya implementación del metodo equals da verdadero si los objectos a comparar son los mismos (es decir, como el ==) por eso tienes que sobreescribir el metodo equals para establecer cual es el criterio de igualdad para tu clase.
Clases ya hechas como String o Integer, pertenecientes a la api de java, ya tienen sobreescrito su método equals.
Hola Justo:
EliminarMuy buena aportación y bien explicado. Seguro que ayuda a mucha gente a entenderlo mejor.
Saludos y muchas gracias.
Muy buen aporte, se agradece este post.
ResponderEliminarMuchas gracias y un saludo.
Muchas gracias. Me alegro que te sirva de ayuda.
EliminarSaludos.
Excelente articulo, de mucha utilidad para mi, gracias.
ResponderEliminarMuy bueno, gracias por compartir :)
ResponderEliminar