I have a custom class called Position. I want to use the following:-
Set<Position> s=new HashSet<Position>();
Do I have to override the HashCode() method in the Position class? I have not overridden equals() method. I want two Position objects to be considered equal only when they are the same object. Do I still have to override HashCode() in order to use the HashSet as shown above?
You only have to override hashcode and equals if you want different objects (presumably representing the same thing) to count as equal.
(To clarify, if you do override one you should override the other, so that objects that test as equal always have the same hashcode.)
Yes! Overwriting one of the two but not the other is very bad style and will create subtle bugs that are hard to debug. There is a contract that is documented in the JavaDoc of Object [1] and this contract should be obeyed in your own interest. If you want to read more about this, read item 7 of the very good book Effective Java [2].
[1] http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html
[2] http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
Edit: Sorry, I read wrong. If you are not overwriting one of them, you don't have to do anything. Still, read the item in the book. It is always a good idea to implement these both methods.
If you were using a Map, then there is a special class called IdentityHashMap which is built specifically for this purpose, i.e using reference-equality in place of object-equality when comparing keys.
Related
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.
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.
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.
If only some of the fields of an object represents the actual state, I suppose these could be ignored when overriding equals and hashCode...
I get an uneasy feeling about this though, and wanted to ask,
Is this common practice?
Are there any potential pitfalls with this approach?
Is there any documentation or guidelines when it comes to ignoring some fields in equals / hashCode?
In my particular situation, I'm exploring a state-space of a problem. I'd like to keep a hash set of visited states, but I'm also considering including the path which lead to the state. Obviously, two states are equal, even though they are found through different paths.
This is based on how you would consider the uniqueness of a given object. If it has a primary key ( unique key) , then using that attribute alone is enough.
If you think the uniqueness is combination of 10 different attributes, then use all 10 attributes in the equals.
Then use only the attributes that you used in equals to generate the hashcode because same objects should generate the same hashcodes.
Selecting the attribute(s) for equals and hashcode is how you define the uniqueness of a given object.
Is this common practice? Yes
Are there any potential pitfalls with this approach? No
Is there any documentation or guidelines when it comes to ignoring some fields in equals / hashCode?
"The equals method for class Object implements the most discriminating
possible equivalence relation on objects;"
This is from object class Javadoc. But as the author of the class , you know how the uniqueness is defined.
Ultimately, "equals" means what you want it to mean. There is the restriction that "equal" values must return the same hashcode, and, of course, if presented with two identical address "equals" must return true. But you could, eg, have an "equals" that compared the contents of two web pages (ignoring the issue of repeatability for the nonce), and, even though the URLs were different, said "equal" if the page contents matched in some way.
The best documentation/guidelines I have seen for overriding the methods on Object was in Josh Bloch's Effective Java. It has a whole chapter on "Methods Common to All Objects" which includes sections about "Obey the general contract when overriding equals" and "Always override hashCode when you override equals". It describes, in detail, the things you should consider when overriding these two methods. I won't give away the answer directly; the book is definitely worth the cost for every Java developer.
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.