Today I tried to compare two arrays using equals(), it obviously failed, I started diggin' etc etc, and after some research I can't quite figure out: at which point in time the class for an array is being created? Cuz I know that int [] a leads to creation of an array class for integers. Who creates it? Why it was impossible to override Object.equals() so that it doesn't compare two objects and compares elements of arrays instead? Would be very grateful if someone could explain or provide a link, which would help to understand that.
Array doesn't override equals() of the Object class.
So it will not use the equals() method of the objects that it holds when equals() is invoked on an Array.
If you want to compare two arrays of integer, you can use Arrays.equals() method.
If it doesn't suit you, create your own method to compare two array of integers.
But overriding equals() of Array is not possible as the class is final and besides it seems rather a weird approach.
How does HashSet1.retainAll(HashSet2); work behind the scenes?
I am adding objects with identical parameters to two different HashSet, but when I use the above I don't seem to get the right result. I.e it doesn't detect it's actually the same parameters in the object.
Is this method above comparing the actual address of my objects in the set?
If so, how can I go about making it compare parameters of the objects instead.
Perhaps override equals?
I have overwritten the hashCode and .equals methods in my class and this has resulted in the method comparing the correct parameter's rather than object address's. Thanks goes to #marstran for his advice on this matter.
This seems like a silly question but why do we override equals method instead of creating a new method with new name and compare using it?
If I didn't override equals that means both == and equals check whether both references are pointed to same memory location?
This seems like a silly question but why do we override equals method instead of creating a new method with new name and compare using it?
Because all standard collections (ArrayList, LinkedList, HashSet, HashMap, ...) use equals when deciding if two objects are equal.
If you invent a new method these collections wouldn't know about it and not work as intended.
The following is very important to understand: If a collection such as ArrayList calls Object.equals this call will, in runtime, resolve to the overridden method. So even though you invent classes that the collections are not aware of, they can still invoke methods, such as equals, on those classes.
If I didn't override equals that means both == and equals check whether both references are pointed to same memory location?
Yes. The implementation of Object.equals just performs a == check.
You override equals if you are using classes that rely on equals, such as HashMap, HashSet, ArrayList etc...
For example, if you store elements of your class in a HashSet, you must override hashCode and equals if you want the uniqueness of elements to be determined not by simple reference equality.
Yes, if you don't override equals, the default equals implementation (as implemented in the Object class) is the same as ==.
In addition to the main reason, already given in other answers, consider program readability.
If you override equals and hashCode anyone reading your code knows what the methods are for. Doing so tells the reader the criteria for value equality between instances of your class. Someone reading your code that uses equals will immediately know you are checking for value equality.
If you use some other name, it will only confuse readers and cost them extra time reading your JavaDocs to find out what your method is for.
Because equals() is a method of the Object class, which is the superclass of all classes, and due to which it is inherently present in every class you write. Hence every collection class or other standard classes use equals() for object comparsion. If you want your custom class objects to be supported for equality by other classes, you have to override equals() only (since other classes know that for object comparion call equals()). If you are only using your own classes, you might create a new method and make sure everything uses your custom method for comparison.
The equals and hashcode method are special methods, widely used across the java's utility classes specially collection framework, and the wrpper classes e.g. String, Integer have overridden this method, So e.g. if you are placing any Object of your choice which has correct equals and hashcode implementation inside the HashSet, to maintain the property of uniqueness the hashcode will compare with all the existing object in hashset, and if it finds any of the hashcode matching then it looks into the equals method to double check if both are really equal and if that equality check also is pass then incoming object is rejected, but if the hashcode equality check is not passed then hashset will not go for the equals method and straight way place that object into the hashset. So we need to make sure the implementation of equals and hashcode is logically proper.
A class like HashMap<T,U> needs to have some means of identifying which item in the collection, if any, should be considered equivalent to a given item. There are two general means via which this can be accomplished:
Requiring that anything to be stored in a collection must include virtual methods to perform such comparison (and preferably provide a quick means (e.g. hashCode()) of assigning partial equivalence classes).
Require that code which creates the collection must supply an object which can accept references to other objects and perform equivalence-related operations upon them.
It would have been possible to omit equals and hashCode() from Object, and have types like HashMap only be usable with key types that implement an equatable interface that includes such members; code which wishes to use collections of references keyed by identity would have to use IdentityHashMap instead. Such a design would not have been unreasonable, but the present design makes it possible for a general-purpose collection-of-collections type which uses HashMap to be usable with things that are compared by value as well as by identity, rather than having to define a separate types for collection-of-HashMap and collection-of-IdentityHashMap.
An alternative design might have been to have a GeneralHashMap type whose constructor requires specifying a comparison function, and have IdentityHashMap and HashMap both derive from that; the latter would constrain its type to equatable and have its identity functions chain to those of the objects contained therein. There would probably have been nothing particularly wrong with that design, but that's not how things were done.
In any case, there needs to be some standard means by which collections can identify items that should be considered equivalent; using virtual equals(Object) and getHashCode() is a way of doing that.
Question 1
There are Two things.
equals() is Located inside Object class
Collection framework using equals() and hashcode() methods when comparing objects
Question 2
Yes for comparing two Object. but when You comparing two String Objects using equals() its only checking the value.
I'm using a TreeMap (SortedMap) whose keys are Object[] with elements of varying types.
TreeMap's equals() doesn't work on Object[] like Arrays's equals() would do -- which means it won't work when using its methods like containsKey() and get() unless I workaround it.
Is there somewhere a solution for this that doesn't involve creating a whole new Class?
EDIT :
Just to make it clear, I made a mistaken assumption. Creating a new Comparator(){} also does affect every method that uses equality, such as equals(), not only the tree sorter.
Is there somewhere a solution for this that doesn't involve creating a whole new Class?
No. In fact, you shouldn't be using mutable values for map keys at all.
While I agree with Matt Ball that you generally shouldn't use mutable (changeable) types as your keys, it is possible to use a TreeMap in this manner as long as you are not planning on modifying the arrays once they are in the tree.
This solution does involve the creation of a class, but not a new Map class, which is what it seems you are asking. Instead, you would need to create your own class which implements Comparator<Object[]> that can compare arrays. The class could use the Arrays.equals() method to determine if they are equal, but would need to also have a consistent rule to determine which array comes before another array when the arrays are not equal.
It looks like hashCode() and equals() are declared as final. So overriding the implementation is not possible. It also states that equals() returns true if the objects are JavaScript identical (triple-equals). I'm not quite sure what that means as creating two identical JavaScriptObject's in GWT and comparing them with equals() returns false. Also it looks like hashcode() uses a monotonically increasing counter to assign a hash code to the underlying JavaScript object. If I wanted to store JavaScriptObjects in a Set this would complicate things. Any help would be much appreciated.
It depends on which equality criteria you want to use for your situation.
If you want object identity, you can use the predefined equals() and hashCode() - and put the JavaScriptObjects directly in a HashSet.
If you need a different equality notion, you can write your own Comparator and put the JavaScriptObjects in e.g. a TreeSet, created by new TreeSet(comparator).
If you need to put JavaScriptObjects in a HashSet (not a TreeSet), and still need a different equality notion, you can't put the JavaScriptObjects directly in the Set. Then you'd have to write a wrapper class, which contains the JavaScriptObject, and implements equals() and hashCode().