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));
}
输出
C null 3
B null 2
A null 1
请解释为什么我从map2
获取空值,即使在map2.putAll(map1)
奇怪的是,当我遍历条目时,迭代器正在提供正确的输出
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 正如所回答的问题是与比较它正在与
一起使用 TreeMap<String, Integer> map2 = new TreeMap<>((str1, str2) -> str1.equals(str2) ? 0 : map1.get(str1) - map1.get(str2) > 0 ? -1 : 1);
答案 0 :(得分:2)
当地图值相等时,您错过了在比较器中返回零:
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;
}
});
来自TreeMap
的文档:
请注意,树映射维护的顺序(如任何有序映射)以及是否提供显式比较器必须与
equals
一致,如果此有序映射是正确实现Map接口。 (有关与equals 一致的精确定义,请参阅Comparable
或Comparator
。)这是因为Map
接口是根据{{1操作,但是有序地图使用其equals
(或compareTo
)方法执行所有关键比较,因此通过此方法认为相同的两个关键字来自有序地图的立场,相等。即使排序与compare
不一致,也可以很好地定义有序映射的行为。它只是没有遵守equals
接口的一般合同。
答案 1 :(得分:0)
检查TreeMap源代码
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;
}
它使用比较器来获取条目,就像二进制搜索一样。 你的比较器返回0,然后TreeMap永远找不到该条目,所以返回null。