use of equals() method in comparator interface? - java

equals() method is available to all java collection classes from the Object class. This method is also declared in Comparator interface, so what is the purpose of declaring this method in Comparator? in which case is it used and how?

what is the purpose of declaring this method in Comparator?
I think it's the designer's way of highlighting the fact that Comparator.equals() imposes some additional requirements on any classes that implement the interface:
Additionally, this method can return true only if the specified object is also a comparator and it imposes the same ordering as this comparator. Thus, comp1.equals(comp2) implies that sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2)) for every object reference o1 and o2.
The method can be used to establish whether or not two distinct comparators impose the same order.

I think that the main reason is to make it clear that equals method is for testing the Comparator itself. This is obvious when you think about it, but can I imagine that some people might expect equals(Object) to (somehow) be semantically related to the compare(T, T) method.
It also allows the documentation of some common-sense guidelines for when two comparators could be viewed as equal.
Either way, the presence of the equals(Object) method in the interface is solely for documentation purposes.

From the javadoc
Note that it is always safe not to override Object.equals(Object).
However, overriding this method may, in some cases, improve
performance by allowing programs to determine that two distinct
comparators impose the same order.
The idea is simply to be able to allow you to not sort a collection that has already been sorted by another comparator if you realize that the end result will be the same.
Generally it had little use, but when sorting very large collections it is something you might want to look into.

-when the declaring Comparator is compared to another Object (argument)

It's just an over-ridden form of the Object's equals method to let you know if two objects are of same comparator type.

As per your question I think It is used to compare objects after converting in string.
Object class eqlas methods chek both Object are eqls or not And Competres method chek object data like Hello.eqlas("hello")

Related

Why doesn't ArrayDeque override equals() and hashCode()?

EDITED: Now only ArrayDeque is considered. (I originally thought LinkedList also doesn't override the two methods.)
Collection type ArrayDeque simply uses the hashCode and equals method implementations that it inherits from Object.
Why doesn't it instead override these methods with proper implementations (i.e. hash and equality test based on contained elements)?
LinkedList extends AbstractSequentialList which extends AbstractList which does override equals and hashCode - so the implementation is not inherited from Object.
ArrayDeque, on the other hand, really doesn't inherit anything other implementation as far as I can see. Its direct superclass (AbstractCollection) doesn't override them. This feels like an exception rather than the rule - I believe most collection implementations in Java "do the right thing".
I don't know of the justification for ArrayDeque choosing not to implement equality, but if you want to compare two deques you could easily just convert them into lists or arrays and do it that way.
They are overrided in AbstractList, that is present in LinkedList inheritance
It generally does not make sense for object instances which are going to be mutated to report themselves as equal to anything other than themselves. The primary reason that instances of some mutable collection types report themselves as equal to other collection instances that it is common for code to hold references to instances which, even though they "could" be mutated, won't be. Although code could hold references to two ArrayDequeue for the purpose of encapsulating all of the items that have ever been or are ever going to be put in them, and it might make sense to compare the contents of two ArrayDequeue instances which are held for that purpose, the whole purpose of the type is to facilitate the pushing and popping of items; in cases where it would make sense for equals to check for identical content, it would likely also make sense to extract the contents into a type whose purpose is to encapsulate a list.
According to official Javadoc - you're not correct. LinkedList use equals from AbstractList, that perform deep equals
For more information - look at this - http://docs.oracle.com/javase/6/docs/api/java/util/AbstractList.html#equals(java.lang.Object)
With Guava you can use the Iterables.elementsEqual method.

Using multiple alternatives of hashCode() and equals() for sets

Suppose I have a simple POJO class Class1 , and it has 2 fields of type int.
I've implemented the hashCode() and equals() methods of it to handle exactly those 2 fields, in order to put instances of the class into a set.
So far so good.
Now, I want to have a different set, which considers instances of Class1 to be equal if the first field is equal , making the equality condition weaker. I might even want to have another set which considers only the second field as the one that checks for equality.
Is it possible? If so, how?
You can get that effect by using a TreeSet when providing a custom Comparator that only inspects the fields you're interested in.
Note, however, that strictly speaking such a TreeSet no longer is a "correct" Set because it effectively ignores the equal() method of your objects:
Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.
The standard Java libraries don't support this.
And (surprisingly) there doesn't appear to be a Map or Set class in the Apache Commons Collections or Guava libraries that supports this.
There are probably other libraries that to support this if you look hard enough.
Alternatively, you could write your own ... starting with the standard HashMap code.
A cheap-and-cheerful alternative is to create a light-weight wrapper class for your element type that delegates most methods to the wrapped class and provides a different equals / hashcode pair to the original. There is a small runtime penalty in doing this ... but it is worth considering.
Joachim's suggestion is good too, unless your sets are likely to be particularly big. (TreeSet has O(logN) lookup compared with O(1) for a properly implemented hash table.)

overriding Object methods good programming practice?

for a programming project we made about two dozen classes which we need. Is it good programming practice to override equals() and hashcode() functions from Object even though we are not using them? We think it might be good in case we need them in future, but we are not sure.
Unless you need a different implementation of equals and hashCode than those supplied by Object, don't override them. As described in the JavaDoc, the Object version...
...implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
You only override them if you need a different meaning for equals (as, say, String does). (And you are quite correct that if you override one, you almost always need to override the other.)
Not really. Do it only when you need them.
There's no point coding something that you know you won't need.
OTOH, equals and hashCode are very useful to override, and you might easily be using them without realising, e.g.
Putting objects in a HashMap
Testing for equality indirectly, e.g. with a unit test assertEquals
Testing if an object is present in a collection
Basically, if you object has value semantics, is used as "data" in some way and is not a singleton then you will probably end up having to override equals for one or more of the above reasons.
I would hesitate to override some methods simply because you "may" need them. Let the need arise, then solve the issue. Default implementations of these methods are provided and will work out of the box with collections, adding your own implementation may create issues.
Some methods use equals even if you don't call it directly.
You should do it only if you really need it. (If Object.equals() and Object.hashcode() doesn't do what it needs to for your class)
you should override equals() and hashCode() when you need to and you should ALWAYS override toString()
Do not override it unless you really need it. You really need to override these methods when you try to use these objects as a key for HashMap.

Adding check in .equals() for different value type

I have a class with a few fields, one of which is an int, and 2 are long. What I'm thinking of doing is adding in a check in equals() so if an Integer object is passed in, it will compare the int field, and if the same return true. Likewise, if Long is passed in, if it is between the 2 long fields, it will return true.
So, if I add several of these objects to a List or Set, I can then do a get() and have it automatically give me the first object that matches. My thought is if I do this, then I simply make the get() call, and then I'll have it, instead of having to have an extra loop & checks.
Is this a good idea or bad idea compared to simply iterating over all of the objects and doing the comparisons that way?
Don't do this.
The equals() method has a well-defined contract, and your proposed implementation violates it. For example, it won't be symmetric; if x is your object and y is an Integer, y.equals(x) will be false even when x.equals(y) is true. Breaking these rules will confuse anyone who has to work with your codeā€”even yourself, in the future, when you are more accustomed to using this method correctly.
Your use cases sound like they could be satisfied with a NavigableMap, where keys are integers, and values are instances of your class.
The performance will be the same but the code will be obfuscated. A different developer (or yourself in a couple of month) will just expect equals() to check if an object is equal.
I would go for a more explicit solution.
Your equals method should have one concrete implementation without depending on the type of Object being passed, read the equals contract here as anyone reading your code or javadoc will expect it to be as per the contract.
For such cases you can write your own custom Comparator and use it to search your objects in collection.
Or have separate equals method like checkIntEquality and checkLongEquality and call them as appropriate.
That only makes sense if the semantics of the object follow the same logic.
If the different types represent different values, with different meanings, this type of overloading generates confusion.
It also sounds like the "equals" for longs isn't even an equals, which is worse.
Encapsulating the behavior in the object is fine, but should be named sensibly.

Overriding the equals method vs creating a new method

I have always thought that the .equals() method in java should be overridden to be made specific to the class you have created. In other words to look for equivalence of two different instances rather than two references to the same instance. However I have encountered other programmers who seem to think that the default object behavior should be left alone and a new method created for testing equivalence of two objects of the same class.
What are the argument for and against overriding the equals method?
Overriding the equals method is necessary if you want to test equivalence in standard library classes (for example, ensuring a java.util.Set contains unique elements or using objects as keys in java.util.Map objects).
Note, if you override equals, ensure you honour the API contract as described in the documentation. For example, ensure you also override Object.hashCode:
If two objects are equal according to
the equals(Object) method, then
calling the hashCode method on each of
the two objects must produce the same
integer result.
EDIT: I didn't post this as a complete answer on the subject, so I'll echo Fredrik Kalseth's statement that overriding equals works best for immutable objects. To quote the API for Map:
Note: great care must be exercised if
mutable objects are used as map keys.
The behavior of a map is not specified
if the value of an object is changed
in a manner that affects equals
comparisons while the object is a key
in the map.
I would highly recommend picking up a copy of Effective Java and reading through item 7 obeying the equals contract. You need to be careful if you are overriding equals for mutable objects, as many of the collections such as Maps and Sets use equals to determine equivalence, and mutating an object contained in a collection could lead to unexpected results. Brian Goetz also has a pretty good overview of implementing equals and hashCode.
You should "never" override equals & getHashCode for mutable objects - this goes for .net and Java both. If you do, and use such an object as the key in f.ex a dictionary and then change that object, you'll be in trouble because the dictionary relies on the hashcode to find the object.
Here's a good article on the topic: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx
#David Schlosnagle mentions mentions Josh Bloch's Effective Java -- this is a must-read for any Java developer.
There is a related issue: for immutable value objects, you should also consider overriding compare_to. The standard wording for if they differ is in the Comparable API:
It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."
The Equals method is intended to compare references. So it should not be overriden to change its behaviour.
You should create a new method to test for equivalence in different instances if you need to (or use the CompareTo method in some .NET classes)
To be honest, in Java there is not really an argument against overriding equals. If you need to compare instances for equality, then that is what you do.
As mentioned above, you need to be aware of the contract with hashCode, and similarly, watch out for the gotchas around the Comparable interface - in almost all situations you want the natural ordering as defined by Comparable to be consistent with equals (see the BigDecimal api doc for the canonical counter example)
Creating a new method for deciding equality, quite apart from not working with the existing library classes, flies in the face of Java convention somewhat.
You should only need to override the equals() method if you want specific behaviour when adding objects to sorted data structures (SortedSet etc.)
When you do that you should also override hashCode().
See here for a complete explanation.

Categories