Is it possible to override Object#equals(Object)
locally when using list.contains(someObject)
?
Example:
class SomeObject {
...
private int id;
private String name;
@Overrdide
public boolean equals(Object other){
...
return this.id == other.id;
}
}
But what if I want another kind of equals when I use list.contains(someObject)
? For example I want to know if a list contains a certain name? Is it possible to override Object#equals(Object)
'anonymously'?
More specific explanation why I would need it:
int objectId = ... // Some event which passes me the attribute of an object but not the object itself
Now I have List<SomeObject> someObjects
and I would like to know if this list contains an object with objectId
without necessarily iterating over it.
One "solution" I could think of would be using Map<Integer, SomeObject> mapping
and then someObject = mapping.get(objectId)
EDIT: My question is not a duplicate since I am specifically asking to override Object#equals(Object)
.
Method Overriding Example We have two classes: A child class Boy and a parent class Human. The Boy class extends Human class. Both the classes have a common method void eat() . Boy class is giving its own implementation to the eat() method or in other words it is overriding the eat() method.
Object , hereafter referred to simply as Object , as a base class. Because of this, all Java classes inherit methods from Object . Half of these methods are final and cannot be overridden. However, the other methods in Object can be and are overridden, often incorrectly.
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides.
You can apply a filter on a stream object obtained from the list. The filter takes a predicate where you can set the condition. Then you can check if the filtered stream is not empty:
list.stream().filter(e -> e.name.equals(otherName)).findAny().isPresent()
You can make it reusable as follows for example:
private <T> boolean containsWithPredicate(List<T> list, Predicate<T> predicate) {
return list.stream().filter(predicate).findAny().isPresent();
}
and call it as follows:
boolean containsElement = containsWithPredicate(myListOfObjects,
(e -> e.name.equals(otherName)));
EDIT:
There is a much simpler way of doing the exact same above by just calling Stream.anyMatch
instead of doing filter
then findAny
:
list.stream().anyMatch(predicate);
You can use a TreeSet
with a custom Comparator
to achieve what you want. It doesn't use equals()
for equality, but rather considers that if compare()
returns 0
, objects are equal.
Let's say we want all Strings
to be equal if they are the same length:
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
This can be a useful construct (works with TreeMap
as well) in cases where you need to have different "equality definitions" for objects at different times, while still working with collections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With