Reputation: 198
TreeMap<String, Integer> map1 = new TreeMap<String, Integer>();
map1.put("A", 1); map1.put("B", 2); map1.put("C", 3);
TreeMap<String, Integer> map2 = new TreeMap<>((str1, str2) -> map1.get(str1) - map1.get(str2) > 0 ? -1 : 1);
map2.putAll(map1);
Iterator<String> iterator = map2.keySet().iterator();
while(iterator.hasNext()) {
String key = iterator.next();
System.out.println(key + " " + map2.get(key) + " " + map1.get(key));
}
Output of this is
C null 3
B null 2
A null 1
Please explain why I am getting null values from map2
, even after doing map2.putAll(map1)
Strangely when I iterate through entry iterator is giving the right output
Iterator<Entry<String, Integer>> entryIterator = map2.entrySet().iterator();
while(entryIterator.hasNext()) {
Entry<String, Integer> entry = entryIterator.next();
System.out.println(entry.getKey() + " " + entry.getValue());
}
EDIT As answered issue was with comparator. It is working with
TreeMap<String, Integer> map2 = new TreeMap<>((str1, str2) -> str1.equals(str2) ? 0 : map1.get(str1) - map1.get(str2) > 0 ? -1 : 1);
Upvotes: 4
Views: 663
Reputation: 1356
Check the TreeMap source code
final Entry<K,V> getEntryUsingComparator(Object key) {
@SuppressWarnings("unchecked")
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
Entry<K,V> p = root;
while (p != null) {
int cmp = cpr.compare(k, p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
}
return null;
}
it using comparator to get the entry, like binary search. your comparator return 0, then TreeMap never can find the entry, so return null.
Upvotes: 0
Reputation: 72884
You missed returning zero in the comparator when the map values are equal:
TreeMap<String, Integer> map2 = new TreeMap<>(
new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
if(map1.get(str1).equals(map1.get(str2))) {
return 0;
}
return map1.get(str1) - map1.get(str2) > 0 ? -1 : 1;
}
});
From the documentation of TreeMap
:
Note that the ordering maintained by a tree map, like any sorted map, and whether or not an explicit comparator is provided, must be consistent with
equals
if this sorted map is to correctly implement the Map interface. (SeeComparable
orComparator
for a precise definition of consistent with equals.) This is so because theMap
interface is defined in terms of theequals
operation, but a sorted map performs all key comparisons using itscompareTo
(orcompare
) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal. The behavior of a sorted map is well-defined even if its ordering is inconsistent withequals
; it just fails to obey the general contract of theMap
interface.
Upvotes: 2