java - profe - .Contains() método que no llama al método de Igualdad Anulada
metodo de igualacion youtube (3)
Tengo un problema en el que hago una ArrayList de objetos Foo, anulo el método de iguales y no puedo obtener el método de contenido para llamar al método de iguales. He intentado anular iguales y hashcode juntos, pero todavía no funciona. Estoy seguro de que hay una explicación lógica de por qué esto es así, pero no puedo resolverlo en este momento por mi cuenta. Solo quiero una forma de ver si la lista contiene la ID especificada.
Aquí hay un código:
import java.util.ArrayList;
import java.util.List;
public class Foo {
private String id;
public static void main(String... args){
Foo a = new Foo("ID1");
Foo b = new Foo("ID2");
Foo c = new Foo("ID3");
List<Foo> fooList = new ArrayList<Foo>();
fooList.add(a);
fooList.add(b);
fooList.add(c);
System.out.println(fooList.contains("ID1"));
System.out.println(fooList.contains("ID2"));
System.out.println(fooList.contains("ID5"));
}
public Foo(String id){
this.id = id;
}
@Override
public boolean equals(Object o){
if(o instanceof String){
String toCompare = (String) o;
return id.equals(toCompare);
}
return false;
}
@Override
public int hashCode(){
return 1;
}
}
SALIDA: falso falso falso
Debes implementar hashCode
@Override
public int hashCode() {
return id.hashCode();
}
a pesar de que el contiene funciona para ArrayList sin él. Sus grandes problemas son que sus iguales esperan cadenas, no objetos Foo y que usted pide que contengan cadenas. Si la implementación le preguntó a cada expulsión en la lista si eran iguales a la cadena que envía, entonces su código podría funcionar, pero la implementación le preguntará a la cadena si es igual a sus objetos Foo, lo cual, por supuesto, no lo es.
Usar iguales
@Override
public boolean equals(Object o){
if(o instanceof Foo){
String toCompare = ((Foo) o).id;
return id.equals(toCompare);
}
return false;
}
y luego comprobar contiene
System.out.println(fooList.contains(new Foo("ID1")));
El método equals debe modificarse junto con anular la función hashCode (). Actualmente estás comprobando si el objeto con el que te estás comparando es una instancia de String, cuando necesitas verificar los objetos de Foo.
public boolean equals(Object o){
if(o instanceof Foo){
Foo toCompare = (Foo) o;
return this.id.equals(toCompare.id);
}
return false;
}
Si está utilizando Eclipse, recomendaría que Eclipse genere el código de hash e igual para usted yendo a Fuente -> Generar código de hash () y es igual a () ...
Esto se debe a que su equals()
no es simétrico :
new Foo("ID1").equals("ID1");
pero
"ID1".equals(new Foo("ID1"));
no es verdad. Esto viola el contrato equals()
:
El método equals implementa una relación de equivalencia en referencias a objetos que no son nulos:
[...]
Es simétrico : para cualquier valor de referencia no nulo
y
,x.equals(y)
debe devolver verdadero si y solo siy.equals(x)
devuelvetrue
.
Tampoco es reflexivo :
- Es reflexivo : para cualquier valor de referencia no nulo
x
,x.equals(x)
debe devolver verdadero.
Foo foo = new Foo("ID1");
foo.equals(foo) //false!
@mbockus proporciona la implementación correcta de equals()
:
public boolean equals(Object o){
if(o instanceof Foo){
Foo toCompare = (Foo) o;
return this.id.equals(toCompare.id);
}
return false;
}
pero ahora debes pasar la instancia de Foo
a contains()
:
System.out.println(fooList.contains(new Foo("ID1")));
System.out.println(fooList.contains(new Foo("ID2")));
System.out.println(fooList.contains(new Foo("ID5")));
Finalmente, debe implementar hashCode()
para proporcionar resultados consistentes (si dos objetos son iguales , deben tener igual hashCode()
):
@Override
public int hashCode() {
return id.hashCode();
}