为什么java.util.UUID是可比较的?

时间:2018-06-25 20:13:20

标签: java uuid comparable

Java中的

UUID实现Comparable。对我来说,这有点奇怪,因为在几乎所有情况下,UUID都是随机生成的(或从某个地方反序列化的,但仍然可能是最初随机生成的)。

将它们进行比较似乎没有任何意义,除非您使用顺序递增的LSB / MSB手动生成它们,如果您只想要一个非常大的ID号(两个长整数而不是一个普通长整数),这可能是有道理的,但这是我能想到的唯一解释。

5 个答案:

答案 0 :(得分:9)

编辑:正如Turing85在评论中(以及稍后在full-fledged answer中指出的那样),Java的java.util.UUID类实现了RFC 4122。该RFC明确定义了顺序,因此对于此类实现这种顺序是有意义的-即,通过实现Comparable

尽管如此,即使排序不符合任何“业务”逻辑,它也具有许多其他优点。

首先,它允许您保持一致。确定性地运行的系统,其中X总是在Y之前出现,因此更易于维护,调试和使用。

第二,排序对于避免死锁非常有帮助。如果您始终以相同的顺序更新实体(并获取所需的锁),则可以消除X一直在等待Y的锁(X本身正在等待X的锁)的许多陷阱。

最后-为什么不让UUID具有可比性?用于实现compareTo的附加字节码将类的大小增加了可忽略的大小。如果您不将其用作Comparable,则几乎不会受它的困扰,而使其实现Comparable则为类的用户提供了更大的灵活性来照常使用它。

答案 1 :(得分:6)

看着Javadoc of UUID,我们看到它引用了IETF RFC 4122: A Universally Unique Identifier (UUID) URN Namespace。在提到的RFC中,我们找到了与词汇等效项有关的部分:

Rules for Lexical Equivalence:
   Consider each field of the UUID to be an unsigned integer as shown
   in the table in section Section 4.1.2.  Then, to compare a pair of
   UUIDs, arithmetically compare the corresponding fields from each
   UUID in order of significance and according to their data type.
   Two UUIDs are equal if and only if all the corresponding fields
   are equal.

   [...]

   UUIDs, as defined in this document, can also be ordered
   lexicographically.  For a pair of UUIDs, the first one follows the
   second if the most significant field in which the UUIDs differ is
   greater for the first UUID.  The second precedes the first if the
   most significant field in which the UUIDs differ is greater for
   the second UUID.

这意味着:为了完全实现提到的RFC,需要实现定义的顺序。在Java中实现此方法的方法是通过implements Comparable<...>或提供Comparator<...>。由于RFC中定义的顺序是UUID的“自然顺序”,因此让UUID implements Comparable<UUID>只是合乎逻辑的。

关于如何使用该命令或是否应使用该命令,尚无定论。我的论点仅基于标准的实施。是否以及如何使用此命令取决于用户。 Mureinik'sAlexey Romanov's的答案提供了一些原因,说明了为什么要在没有显式利用订单的情况下定义订单。


附录

如果有人赞成我的回答,那么也应该赞成Alexey's answer。我的答案是稍后写的,但遵循相同的论点。此外,Alexey提供了一个示例,说明如何使用此顺序。

答案 2 :(得分:4)

这是必需的,例如将它们放入TreeMap / TreeSet中。 RFC中最相关的报价是

  

UUID具有固定大小(128位),该大小相当小      与其他替代品相比。这很适合进行排序,      各种排序和散列,存储在数据库中,简单      分配,并且总体上易于编程。

     也可以订购本文档中定义的

UUID         从字典上看。对于一对UUID,第一个跟随         如果UUID不同的最高有效字段是第二个         对于第一个UUID更大。如果第二个在第一个之前,         UUID不同的最重要字段对于         第二个UUID。

答案 3 :(得分:1)

某些UUID版本的含义已编码为它们的值:

  

UUID有四种不同的基本类型:基于时间的,DCE   安全,基于名称和随机生成的UUID。

因此,比较UUID很有意义,因为您可以从它们的值中得出含义。您可以松散地说“此UUID早于或晚于此”。

考虑在Wikipedia上定义的版本:

  • 版本1(日期时间和MAC地址)
  • 版本2(日期和MAC地址,DCE安全版本)
  • 第3版和第5版(基于命名空间的名称)
  • 版本4(随机)

您甚至可以在JavaDoc中看到它:

  

变体2(Leach-Salz)UUID的布局如下:   有效长由以下无符号字段组成:

 0xFFFFFFFF00000000 time_low
 0x00000000FFFF0000 time_mid
 0x000000000000F000 version
 0x0000000000000FFF time_hi

请参见How is a Time-based UUID / GUID made

答案 4 :(得分:0)

如果您将其用作ID,就很有意义。

或者如果有必要将对象保留在树状数据结构中。