objetos metodos llenar listas imprimir enteros como clase java object arraylist evaluation

java - metodos - ¿Cómo evalúa los objetos un método ArrayList de contiene()?



listas en java (9)

Digamos que creo un objeto y lo agrego a mi ArrayList . Si luego creo otro objeto con exactamente la misma entrada del constructor, ¿el método contains() evaluará los dos objetos para que sean iguales? Supongamos que el constructor no hace nada gracioso con la entrada y que 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 se debe implementar la class para que contains() devuelva true ?


ArrayList implements la interfaz de lista.

Si observa el Javadoc for List en el método de contenidos, verá que utiliza el método equals() para evaluar si dos objetos son iguales.


Creo que las implementaciones correctas deberían ser

public class Thing { public int value; public Thing (int x) { this.value = x; } @Override public boolean equals(Object object) { boolean sameSame = false; if (object != null && object instanceof Thing) { sameSame = this.value == ((Thing) object).value; } return sameSame; } }


El ArrayList utiliza el método equals implementado en la clase (la clase Thing de su caso) para hacer la comparación de iguales.


Otros carteles han abordado la pregunta sobre cómo funciona ().

Un aspecto igualmente importante de su pregunta es cómo implementar adecuadamente 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 estés tratando de hacer.

Si solo está interesado en la igualdad de objetos, entonces la implementación predeterminada de .equals () (la proporcionada por Object) solo utiliza la identidad (es decir, esta == otra). Si eso es lo que quieres, entonces no implementes equals () en tu clase (déjalo heredar de Object). El código que usted escribió, aunque es correcto si se va para la identidad, nunca aparecería en una clase real b / c, no proporciona ningún beneficio sobre el uso de la implementación predeterminada Object.equals ().

Si está empezando con estas cosas, le recomiendo 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 la identidad)


Por lo general, también debe anular el hashCode() cada vez que anule equals() , aunque solo sea por el aumento de rendimiento. HashCode() decide en qué ''cubo'' se clasifica su objeto cuando realiza una comparación, por lo que cualquier objeto que se equal() a true equal() devuelve el mismo value() hashCode value() . No puedo recordar el comportamiento predeterminado de hashCode() (si devuelve 0, su código debería funcionar pero lentamente, pero si devuelve la dirección, su código fallará). Recuerdo un montón de veces cuando mi código falló porque olvidé anular hashCode() . :)


Solo quería señalar que la siguiente implementación es incorrecta cuando el value no es un tipo primitivo:

public class Thing { public Object value; public Thing (Object x) { this.value = x; } @Override public boolean equals(Object object) { boolean sameSame = false; if (object != null && object instanceof Thing) { sameSame = this.value == ((Thing) object).value; } return sameSame; } }

En ese caso propongo lo siguiente:

public class Thing { public Object value; public Thing (Object x) { value = x; } @Override public boolean equals(Object object) { if (object != null && object instanceof Thing) { Thing thing = (Thing) object; if (value == null) { return (thing.value == null); } else { return value.equals(thing.value); } } return false; } }


Utiliza el método de iguales en los objetos. Por lo tanto, a menos que Thing reemplace sea igual y use las variables almacenadas en los objetos para la comparación, no devolverá verdadero en el método contains() .


Acceso directo desde JavaDoc :

booleano 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))


class Thing { public int value; public Thing (int x) { value = x; } equals (Thing x) { if (x.value == value) return true; return false; } }

Debes escribir:

class Thing { public int value; public Thing (int x) { value = x; } public boolean equals (Object o) { Thing x = (Thing) o; if (x.value == value) return true; return false; } }

Ahora funciona ;)