Digamos que creo un objeto y lo agrego a mi ArrayList
. Si luego creo otro objeto con exactamente la misma entrada del constructor, ¿evaluará el contains()
método que los dos objetos sean iguales? Suponga que el constructor no hace nada divertido con la entrada, y las variables almacenadas en ambos objetos son idénticas.
ArrayList<Thing> basket = new ArrayList<Thing>();
Thing thing = new Thing(100);
basket.add(thing);
Thing another = new Thing(100);
basket.contains(another); // true or false?
class Thing {
public int value;
public Thing (int x) {
value = x;
}
equals (Thing x) {
if (x.value == value) return true;
return false;
}
}
¿Es así como class
debería implementarse para tener contains()
retorno true
?
java
object
arraylist
evaluation
Mantas Vidutis
fuente
fuente
Object
lugar de unThing
. Si no lo hace, su método igual no será utilizado. :)Collections
hacer sus cosas de manera optimizada, lo que significa quecontains()
primero verifica los correos electrónicoshashCode
de los dos objetos, y solo luego llamaequals()
. Si loshashCode
s son diferentes (que siempre es el caso para dos instancias diferentes deThing
),equals()
no se llamará al método. Como regla general, cuando anulaequals()
, no debe olvidar anularhashCode()
también.Creo que las implementaciones correctas deberían ser
fuente
if
declaración es innecesaria.instanceof
es suficiente.object != null
condición es innecesaria, porqueobject instanceof Thing
verifica que el objeto no sea nulo también.ArrayList utiliza el método de igualdad implementado en la clase (la clase Thing de su caso) para hacer la comparación de igualdad.
fuente
En general, también debe anular
hashCode()
cada vez que anulaequals()
, incluso si solo es para aumentar el rendimiento.HashCode()
decide en qué 'cubo' se ordena su objeto al hacer una comparación, por lo que dos objetos que seequal()
evalúen como verdaderos deberían devolver lo mismohashCode
value()
. No puedo recordar el comportamiento predeterminado dehashCode()
(si devuelve 0, entonces su código debería funcionar pero lentamente, pero si devuelve la dirección, entonces su código fallará). SinhashCode()
embargo , recuerdo muchas veces cuando mi código falló porque olvidé anularlo . :)fuente
Utiliza el método igual en los objetos. Entonces, a menos que Cosa anule la igualdad y use las variables almacenadas en los objetos para comparación, no devolverá verdadero en el
contains()
método.fuente
Debes escribir:
Ahora funciona ;)
fuente
Solo quería señalar que la siguiente implementación es incorrecta cuando
value
no es un tipo primitivo:En ese caso, propongo lo siguiente:
fuente
Otros carteles han abordado la pregunta sobre cómo funciona contiene ().
Un aspecto igualmente importante de su pregunta es cómo implementar correctamente equals (). Y la respuesta a esto depende realmente de lo que constituye la igualdad de objetos para esta clase en particular. En el ejemplo que proporcionó, si tiene dos objetos diferentes que tienen x = 5, ¿son iguales? Realmente depende de lo que intentes hacer.
Si solo está interesado en la igualdad de objetos, entonces el valor predeterminado implementación de .equals () (la provista por Object) usa solo identidad (es decir, esto == otro). Si eso es lo que desea, simplemente no implemente equals () en su clase (deje que herede de Object). El código que escribió, si bien es correcto si busca identidad, nunca aparecerá en una clase real b / c, no proporciona ningún beneficio sobre el uso de la implementación predeterminada Object.equals ().
Si recién está comenzando con estas cosas, le recomiendo encarecidamente el libro Effective Java de Joshua Bloch. Es una gran lectura, y cubre este tipo de cosas (además de cómo implementar correctamente equals () cuando intentas hacer más que comparaciones basadas en identidad)
fuente
Atajo de JavaDoc :
boolean contiene (objeto o)
Devuelve verdadero si esta lista contiene el elemento especificado. Más formalmente, devuelve verdadero si y solo si esta lista contiene al menos un elemento e tal que (o == null? E == null: o.equals (e))
fuente