Почему возможно зациклить keySet
TreeMap и получить .containsKey == false
?
for (Object thisObject : map.keySet()) {
if (!map.containsKey(thisObject)) {
System.out.println("This line should be never reached.");
}
}
После большого количества различных итераций и вызовов эта строка попадает в цель. map.get(thisObject)
вернет null
. Но отладка показывает, что ключ (та же ссылка, значение и хэш) и фактическое значение находятся на карте. Карта небольшая (25 элементов) TreeMap<Long, Double>
ОБНОВЛЕНИЕ:
Как предположил @rgettman, при построении TreeMap используется пользовательская сортировка Comparator
(не видел ее, потому что она была построенный из другого класса). Этот компаратор был просто (я думаю) скопирован из здесь
Изменение Comparator
:
public int compare(Object a, Object b) {
if((Double)base.get(a) > (Double)base.get(b)) {
return 1;
} else if((Double)base.get(a) == (Double)base.get(b)) {
return 0;
} else {
return -1;
}
}
to
...
} else if(base.get(a).equals(base.get(b))) {
return 0;
...
устраняет проблему. Причина, по которой эта проблема появлялась сразу после миллионов операций, заключалась в том, что не было случаев, когда карта имела два одинаковых значения для двух разных ключей, так как это очень маловероятно в данном контексте.
So at:
25151l, 1.7583805400614032
24827l, 1.7583805400614032
это терпит неудачу.
Спасибо за помощь!
==
, не так ли? - person Dennis Meng   schedule 07.08.2013Long thisObject : map.keySet()
? - person Joop Eggen   schedule 07.08.2013Comparator
конструкторуTreeMap
, который нарушает контрактComparator
, т. е. не возвращает0
для равных значений. - person rgettman   schedule 07.08.2013