Sorting With Longs -- Java Collections and Lists
Recently I was sorting lists of files by their modification date. The date was stored as longs, so in the Comparator I subtracted the second file's modified value from the first. Since thecompare()
method requires an int return value, I then
cast to an int. I think when I first did it a little voice in my head
was saying 'lack of precision', but the other little voice in my head
said 'these values will all be pretty close'.
The problem
It turns out the modification dates were sometimes years apart, enough to make the millisecond-based modification dates different by more than the precision of an integer. When a long value that exceeds the capacity of an int is cast to an int, it doesn't throw an exception, but the conversion is not useful, sometimes drastically changing the sign or magnitude of the original value. In my case, comparisons between files whose modification times were more than about 25 days apart produced sometimes-incorrect values fromcompare()
,
resulting in incorrect sorting.
The solution
I usedLong.signum()
to determine whether the difference
was negative, positive, or zero. Then when cast to an
int
it was guaranteed to never be truncated.
public int compare(Item o1, Item o2) { return (int) (Long.signum(o2.getModified() - o1.getModified())); }In Java 8+,
Comparator.comparingLong()
provides similar
functionality.
Copyright © 2024 Andrew Oliver