Проблема
У меня есть 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. Я понимаю, что могу просто изменить структуру этого кода и, вероятно, заставить его работать. Но это должно работать, и я не хочу просто обойти его, если это не известная проблема или что-то еще. Это просто кажется неправильным.