Проблема
У меня есть Map<Date, Foo> и список объектов из базы данных с свойством effectiveDate, и я хочу проверить, соответствуют ли ключи Date на моей карте любой из effectiveDate в базе данных - если да, делайте что-нибудь с Foo.
Код выглядит примерно так:
for (Bar bar : databaseBars) {
Foo foo = new Foo();
if (dateMap.containsKey(bar.getEffectiveDate()) {
foo = dateMap.get(bar.getEffectiveDate());
}
// do stuff with foo and bar
}
Однако вызов dateMap.containsKey всегда возвращает false, хотя я уверен, что он иногда там.
Исследование
Как проверка работоспособности, я распечатал длинные значения дат, а также результаты вызова equals() и вызова compareTo():
for (Date keyDate : dateMap.keySet()) {
if (keyDate == null) {
continue; // make things simpler for now
}
Date effDate = bar.getEffectiveDate();
String template = "keyDate: %d; effDate: %d; equals: %b; compareTo: %d\n";
System.out.printf(template, keyDate.getTime(), effDate.getTime(), effDate.equals(keyDate), effDate.compareTo(keyDate));
}
Результаты:
keyDate: 1388534400000; effDate: 1388534400000; equals: false; compareTo: 0
keyDate: 1420070400000; effDate: 1388534400000; equals: false; compareTo: -1
keyDate: 1388534400000; effDate: 1420070400000; equals: false; compareTo: 1
keyDate: 1420070400000; effDate: 1420070400000; equals: false; compareTo: 0
keyDate: 1388534400000; effDate: 1388534400000; equals: false; compareTo: 0
keyDate: 1420070400000; effDate: 1388534400000; equals: false; compareTo: -1
keyDate: 1388534400000; effDate: 1420070400000; equals: false; compareTo: 1
keyDate: 1420070400000; effDate: 1420070400000; equals: false; compareTo: 0
keyDate: 1388534400000; effDate: 1388534400000; equals: false; compareTo: 0
keyDate: 1420070400000; effDate: 1388534400000; equals: false; compareTo: -1
keyDate: 1388534400000; effDate: 1420070400000; equals: false; compareTo: 1
keyDate: 1420070400000; effDate: 1420070400000; equals: false; compareTo: 0
Вопрос
1) Должны ли equals и compareTo согласиться? (Я предполагаю, что реализация java.util.Date по крайней мере должна попытаться выполнить рекомендацию java.lang.Comparable).
2) Док Date#equals говорит об этом:
Таким образом, два объекта Date являются равными тогда и только тогда, когда метод getTime возвращает одинаковое длинное значение для обоих.
... Похоже, метод getTime возвращает одинаковое длинное значение для обеих этих дат, но equal возвращает false. Любые идеи, почему это может произойти? Я искал высоко и низко, но я не нашел никого, описывающего ту же проблему.
P.S. Я застрял с помощью java.util.Date. Пожалуйста, не просто рекомендуйте JodaTime.
P.P.S. Я понимаю, что могу просто изменить структуру этого кода и, вероятно, заставить его работать. Но это должно работать, и я не хочу просто обойти его, если это не известная проблема или что-то еще. Это просто кажется неправильным.