Effective compareTo() for primitive long

7.6k views Asked by At

Working on a sorted list I came to a point I needed to implement a compareTo() function for primitive long values.

I'm not looking for the obvious naive implementation, but was wondering if there's an elegant one-liner code to do that (without creating a new Long(value)).

Maybe something like this:

@Override public int compareTo(MyClass that) {
    return (int) ((value - that.value) >>> 32);
}

Can anyone verify that would work and/or suggest another implementation?

3

There are 3 answers

8
Evgeniy Dorofeev On BEST ANSWER

One liner code to that:

int res = Long.compare(long x, long y) 

Your code wont work correctly for all values, try it for Integer.MIN_VALUE - Integer.MAX_VALUE and you will get +1

0
moxi On

I found this alternative solution similar to what you suggested:

public static int signum(long i) {
  return (int) ((i >> 63) | (-i >>> 63));
}

I can't take credit for the solution, it's the implementation of: https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#signum(long)

Based on your example, I will use it as:

@Override public int compareTo(MyClass that) {
    return Long.signum(value - that.value);
}

As one of the comments mentioned, is a good idea to start with the built-in JDK functions for common tasks.

0
meriton On

Your algorithm is incorrect, as it returns 0 when asked to compare 1 and 0:

(1 - 0) >>> 32
1 >>> 32
0

In general, I am not sure it is possible to compare longs without branch instructions, because the difference of two longs may not fit in a long without overflowing, which would change the sign of the difference.

I therefore agree with Evgeniy's answer that using the JDK implementation is likely the best approach.