When should I be overriding java.lang.Object methods? - java

Under what circumstances should I begin to consider overriding any of the following methods?
clone()
equals()
finalize()
hashCode()
toString()
Some of these have some obvious, somewhat specific answers, but I'm wondering more so about general conditions under which it would considered good practice to implement them.

clone()
Implement if you want an easy way to copy the object.
Many people discourage use of clone() and suggest using a copy-constructor instead. E.g. see Clone() vs Copy constructor- which is recommended in java.
equals()
Implement if you need to compare two instances for equality.
Required if object will be used as key in a HashMap (or similar), or inserted into a HashSet (or similar). Highly recommended of used in the TreeXxx variants, for compatibility with compareTo(), i.e. if class implements Comparable.
hashCode()
Implement if object will be used as key in a HashMap (or similar), or inserted into a HashSet (or similar).
Generally a good idea to always implement if you implement equals().
toString()
Generally implement to make debugging easier, especially if object will be inserted into a collection.
Implement if object has a simple textual representation, and you want to be able to output it without calling a method (e.g. getName() or getDescription()).
finalize()
Never. No code should rely on finalize() for resource clean-up, since there is no guarantee when, or even if, it will be called.
Resource-owning classes should implement AutoCloseable instead.

Generally I follow the following principle: Always override at least equals() and toString() (maybe even clone(), too) if the software you're creating will be used by others (like an API or something).
If it's just for personal small things I would at least make a toString() since they can be very handy, but it's all up to you: the programmer.

Related

StringBuilder Equals in c# and Java

I have just come across this StringBuilder .equals Java, where java StringBuilder does not have Equals() implementation. However, in c# I observed there is an Equals() implementation available for StringBuilder class. I would particularly want to know how this is handled in C# and why not in Java.
StringBuilder.equals() actually exists, but it does not compare the Strings. From a Java perspective, this is the correct approach. StringBuilders mutate, that's their purpose, which makes two different StringBuilder objects un-equal by definition. Most newer Java APIs follow the approach that equal() is implemented for immutable or final classes, although there are exceptions. Mutable classes, on the other hand, usually simply inherit Object.equals() which relies on object-identity.
There are at least two reasons behind this. One is the ability to properly use objects in hash-based data structures, i.e. as value in a HashSet or a key in a HashMap. Although this depends on Object.hashCode(), it affects Object.equals() because the hashCode should be stable over an object's life time if it is to be used as an entry in a hash-based datastructure, and equals() is defined to be consistent with hashCode().
The other is that Object.equals() is defined to be symmetrical, and carelessly overriding Object.equals() can break that symmetry.
All in all, in Java, Object.equals() shouldn't be understood as value-equality but as equality according to the nature of the instances.

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.

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.

use of equals() method in comparator interface?

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")

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