I just want to be sure that my code is safe using Integer
objects as keys. Here's a short example:
Integer int1 = new Integer(1337);
Integer int2 = new Integer(1337);
if (int1 == int2) {
System.out.println("true");
} else {
System.out.println("false");
}
if (int1.equals(int2)) {
System.out.println("true");
} else {
System.out.println("false");
}
Map<Integer, Object> map = new HashMap<Integer, Object>();
map.put(int1, null);
map.put(int2, null);
System.out.println(map.size());
The code will output
false
true
1
That's what I was expecting, the references differ but they equal each other. Now I'm interested in the Map's behavior.
HashMap
?Entry is a key-value pair. We can compare two HashMap by comparing Entry with the equals() method of the Map returns true if the maps have the same key-value pairs that mean the same Entry.
It can store different types: Integer keys and String values or same types: Integer keys and Integer values. HashMap is similar to HashTable, but it is unsynchronized. It is allowed to store null keys as well, but there can only be one null key and there can be any number of null values.
Keys are unique by default. Note that . keySet() on a Map returns a Set , and elements of a Set are unique by default. If you attempt to push a value to an existing key, the old value will be overwritten.
The method equals
is called, hence it's the content that is compared.
As to your two questions above:
Given two objects o1
and o2
(to simplify, we assume that o1!=null
and o2!=null
), a hasp map, ultimately, has to determine if they have the same value. (ultimately, since HaspMap
also checks if o1
and o2
have the same hash value, but this is not important in the context of your question). It does this by calling the method equals()
. As long as o1.equals(o2)
is false, the two objects are considered two different keys by HashMap
.
HashSet
also calls equals()
to determine if an element is already contained in the set, see http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add%28E%29.
TreeMap
, on the other hand, has to compare the two objects, and determine if they are equal, or which one if greater. It does this by calling compareTo()
. Therefore, it is the return value of o1.compareTo(o2)
which is important (or, if you created the tree map with the constructor http://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html#TreeMap%28java.util.Comparator%29, the comparator is used).
What is guaranteed is therefore that in HashMap
and HashSet
, the method equals()
is used to tell objects apart, and in TreeMap
, the method compareTo()
.
Q1: - Is it guaranteed that Collections like Map or Set will compare the keys by their content and not their reference?
A1: - No. Collection, Map and Set are interfaces. Only thing that they assure is the contract of possible methods.
Q2: - Depends it on the actual implementation, like HashMap?
A2: Yes. How class deals with comparation it is a developer decision.
HashMap use two things to allocate their objects
First - is Object#hashCode()
, that is used to calculate index.
Second - is Object#equals()
, that is used then hash colision have places.
If you open implementation of java.util.AbstractMap
you can see that keys and values equation is checked using Object#equals
method everywhere. What actually will be compared inside map depends on key/value implementation of Object#equals
method.
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