tipos - que es una clase en java
El objeto de reemplazo#es igual a(objeto) fuera de la clase (3)
No hay manera de tener múltiples equals
para la misma clase. Pero puede subclasificar su clase e invalidar hashCode()
y equals()
, luego usar la instancia deseada dependiendo de los equals
que quiera usar.
Debo decir que no me gusta hacer eso, el método de equals
debe estar bien definido, será muy confuso usar múltiples equals
en diferentes escenarios. En lugar de crear subclases, tendría implementaciones totalmente diferentes si tuviera que tener dos métodos equals
. Así que te recomiendo que reconsideres tu diseño.
¿Es posible anular Object#equals(Object)
localmente cuando se usa list.contains(someObject)
?
Ejemplo:
class SomeObject {
...
private int id;
private String name;
@Overrdide
public boolean equals(Object other){
...
return this.id == other.id;
}
}
¿Pero qué list.contains(someObject)
si quiero otro tipo de iguales cuando uso list.contains(someObject)
? Por ejemplo, quiero saber si una lista contiene un nombre determinado. ¿Es posible anular Object#equals(Object)
''anónimamente''?
Explicación más específica por qué lo necesitaría:
int objectId = ... // Some event which passes me the attribute of an object but not the object itself
Ahora tengo la List<SomeObject> someObjects
y me gustaría saber si esta lista contiene un objeto con objectId
sin iterar necesariamente sobre él.
Una "solución" en la que podría pensar sería usar Map<Integer, SomeObject> mapping
y luego someObject = mapping.get(objectId)
EDITAR: Mi pregunta no es un duplicado, ya que solicito específicamente anular Object#equals(Object)
.
Puede aplicar un filtro en un objeto de flujo obtenido de la lista. El filtro toma un predicado donde puede establecer la condición. Luego puedes verificar si el flujo filtrado no está vacío:
list.stream().filter(e -> e.name.equals(otherName)).findAny().isPresent()
Puedes hacerlo reutilizable como sigue por ejemplo:
private <T> boolean containsWithPredicate(List<T> list, Predicate<T> predicate) {
return list.stream().filter(predicate).findAny().isPresent();
}
y llámalo como sigue:
boolean containsElement = containsWithPredicate(myListOfObjects,
(e -> e.name.equals(otherName)));
EDITAR:
Hay una forma mucho más sencilla de hacer lo mismo anteriormente, simplemente llamando a Stream.anyMatch
lugar de hacer un filter
luego encontrar a findAny
:
list.stream().anyMatch(predicate);
Puede usar un TreeSet
con un Comparator
personalizado para lograr lo que desea. No usa equals()
para la igualdad, sino que considera que si compare()
devuelve 0
, los objetos son iguales.
Digamos que queremos que todas las Strings
sean iguales si tienen la misma longitud:
TreeSet<String> set = new TreeSet(new Comparator<>() {
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
}
set.add("asd");
set.contains("foo"); // Returns true
Esta puede ser una construcción útil (también funciona con TreeMap
) en los casos en los que necesita tener diferentes "definiciones de igualdad" para los objetos en diferentes momentos, mientras trabaja con colecciones.