Home > Back-end >  Why does UUID.compareTo() differ from UUID.toString().compareTo() in Java?
Why does UUID.compareTo() differ from UUID.toString().compareTo() in Java?

Time:11-03

In postgresql 13 ordering by myColumn::UUID or by myColumn::text results in the exact same ordering. (uuid_v4)

In Java it doesn't:

List<UUID> uuids = 
        Stream.of(UUID.randomUUID(), UUID.randomUUID())
              .sorted()
              .collect(Collectors.toList());

UUID uuid1 = uuids.get(0);
UUID uuid2 = uuids.get(1);

Assert.assertEquals(
        Math.signum((int) uuid1.compareTo(uuid2)),
        Math.signum((int) uuid1.toString().compareTo(uuid2.toString()))); // postgresql orders like this
java.lang.AssertionError: 
Expected :-1
Actual   :1

I am intrigued by the reason behind Java ordering UUID's in a way that is inconsistent with the ordering of their String representations and with the database altogether.

It feels like UUID.toString() is using the least and most significant bits the wrong way around(?) It's using the least significant for the beginning of the representation instead of the most significant.

  • PostgreSQL 13.4
  • Java 11.0.5

CodePudding user response:

Well, in one case you compare UUIDs, in another case two string in lexical order.

According to the Javadoc:

The first of two UUIDs is greater than the second if the most significant field in which the UUIDs differ is greater for the first UUID.

CodePudding user response:

It's because Java doesn't have unsigned types, and UUIDs are compared by comparing two pairs of signed longs. It's frustrating.

  • Related