UUIDs are an important element of programmers’ daily activities. In Java, as in practically every other language, we make extensive use of UUIDs to generate unique identifiers.
There is a special class called java.util.UUID that exists solely to represent immutable universally unique identifiers. According to Java documentation, there are four primary sorts of UUIDs: time-based, DCE security, name-based, and randomly generated UUID. These kinds have version values 1, 2, 3, and 4, correspondingly.
Features
There only three factory methods that can create a new UUID:

The most popular way to generate UUIDs in Java is to use a static method randomUUID(), which returns UUIDs of type 4 — pseudorandomly generated ones:
public static UUID randomUUID()
For sure, since it creates UUIDs of type 4, there are no chances to compare the results. The code snippet below will return random comparison results each run due to the random nature of these UUIDs:
public static void main(String[] args) {
UUID earlieruUid = UUID.randomUUID();
UUID laterUid = UUID.randomUUID();
System.out.println(earlieruUid.compareTo(laterUid));
}
So that means the usage of the Type 4 UUIDs makes comparisons between two UUIDs unpredictable, and it is clearly follows from the compareTo() implementation:
@Override
public int compareTo(UUID val) {
// The ordering is intentionally set up so that the UUIDs
// can simply be numerically compared as two numbers
int mostSigBits = Long.compare(this.mostSigBits, val.mostSigBits);
return mostSigBits != 0 ? mostSigBits : Long.compare(this.leastSigBits, val.leastSigBits);
}
If you try to invoke a timestamp() method on such UUID that has a type different from Type 1, you’ll get the exception:
java.lang.UnsupportedOperationException: Not a time-based UUID
Java specification doesn’t require an implementation for a constructor of Type 1, that is based on the current timestamp and a MAC address. Probably it wasn’t implemented due to security reasons. However, there are plenty of third-party libraries that are able to do it for you (see JUG).
The second option is to create a UUID using the fromString():

The method generates a UUID of Type 4 (Randomly generated) from the standard representation. It may appear useful in the presence of a unique string representation, but in practice, this is a rare thing.
The method is guaranteed to return equal UUIDs for the same string representations. The code snippet below always returns 0:
public static void main(String[] args) {
UUID firstUid = UUID.fromString("be7a1bd0-b44a-4a6f-a91f-ad819abcaf0e");
UUID secondUid = UUID.fromString("be7a1bd0-b44a-4a6f-a91f-ad819abcaf0e");
System.out.println(firstUid.compareTo(secondUid));
}
The last factory method is UUID.nameUUIDFromBytes() works similar to the previous one, but receives a byte array as an argument and returns a UUID of Type 3 (Name-based). The code snippet below also always returns 0:
public static void main(String[] args) {
UUID firstUid = UUID.nameUUIDFromBytes("be7a1bd0-b44a-4a6f-a91f-ad819abcaf0e".getBytes());
UUID secondUid = UUID.nameUUIDFromBytes("be7a1bd0-b44a-4a6f-a91f-ad819abcaf0e".getBytes());
System.out.println(firstUid.compareTo(secondUid));
}
Conclusions
In practice, the most common way to create UUIDs in Java is the randomUUID() method. In the majority of cases, it is good enough to provide uniqueness. Since it is randomly generated, there are no options to compare such UUIDs or to extract a timestamp as additional metadata, which can be useful in some scenarios.
So off-the-shelf Java can generate Name-based and randomly generated UUIDs. Both are comparable (though the second option only in some cases) but need unique identifiers at the construction time, which cuts down on functionality. Feel free to use third-party libraries that provide options for Time-based UUIDs.