Problem
I have a Map<Date, Foo>
, and a list of objects from the database with an effectiveDate
property, and I want to check to see if the Date
keys in my map are equal to any of the effectiveDate
s in the database - if so, do stuff with Foo
.
The code looks something like this:
for (Bar bar : databaseBars) {
Foo foo = new Foo();
if (dateMap.containsKey(bar.getEffectiveDate()) {
foo = dateMap.get(bar.getEffectiveDate());
}
// do stuff with foo and bar
}
However, the dateMap.containsKey
call always returns false, even though I'm sure it's sometimes there.
Investigation
As a sanity check, I've printed out the long values of the dates, as well as the results of an equals()
call and a compareTo()
call:
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));
}
The results:
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
Question
1) Shouldn't equals
and compareTo
agree? (I assume the implementation of java.util.Date
at least should try to follow the recommendation of java.lang.Comparable
).
2) The Date#equals
doc says this:
Thus, two Date objects are equal if and only if the getTime method returns the same long value for both.
...Looks like the getTime
method returns the same long value for both of these dates, yet equal
returns false. Any ideas why this might be happening? I've searched high and low, but I haven't found anyone describing the same problem.
P.S. I'm stuck using java.util.Date
. Please don't just recommend JodaTime.
P.P.S. I realize I could just change the structure of this code and probably get it working. But this should work, and I don't want to just work around it, unless it's a known issue or something. It just seems wrong.