在处理用例时,需要对数据进行排序,这些数据都是基于Type 1或基于时间的UUID并使用Datastax Cassandra Java驱动程序库(UUIDS.timebased())生成,但我发现UUID.compareTo没有对某些UUID.compareTo进行排序正确的UUID。
compareTo中的逻辑是

    /**
 * Compares this UUID with the specified UUID.
 *
 * <p> 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.
 *
 * @param  val
 *         {@code UUID} to which this {@code UUID} is to be compared
 *
 * @return  -1, 0 or 1 as this {@code UUID} is less than, equal to, or
 *          greater than {@code val}
 *
 */
public int compareTo(UUID val) {
    // The ordering is intentionally set up so that the UUIDs
    // can simply be numerically compared as two numbers
    return (this.mostSigBits < val.mostSigBits ? -1 :
            (this.mostSigBits > val.mostSigBits ? 1 :
             (this.leastSigBits < val.leastSigBits ? -1 :
              (this.leastSigBits > val.leastSigBits ? 1 :
               0))));
}

我使用java的datastax cassandra驱动程序生成了以下2个UUID。
UUID uuid1 = java.util.UUID.fromString("7fff5ab0-43be-11ea-8fba-0f6f28968a17")
UUID uuid2 = java.util.UUID.fromString("80004510-43be-11ea-8fba-0f6f28968a17")
uuid1.timestamp() //137997224058510000
uuid2.timestamp() //137997224058570000

从上面可以明显看出,uuid1小于uuid2,但是当我们使用UUID compareTo方法比较它们时,将得到不同的输出。我们应该得到的输出应该是-1,因为它应该小于,但是我们得到的答案是1,这表明该uuid1大于uuid2
uuid1.compareTo(uuid2) //output - 1

通过进一步分析,发现uuid2的msb转换为负数,其中uuid1的msb为正数。因此,compareTo中的逻辑返回值1而不是-1。
u_7fff5ab0 = {UUID@2623} "7fff5ab0-43be-11ea-8fba-0f6f28968a17"
mostSigBits = 9223190274975338986
leastSigBits = -8090136810520933865

u_80004510 = {UUID@2622} "80004510-43be-11ea-8fba-0f6f28968a17"
mostSigBits = -9223296100696452630
leastSigBits = -8090136810520933865

UUID及其相互比较是否正常?
如果是这样,那么我们如何处理此类基于时间的UUID的排序?

谢谢

最佳答案

请注意,比较基于时间的UUID需要特别注意From the docs:



基于时间的UUID不应与java.util.UUID#compareTo进行比较。要比较两个基于时间的UUID,您应该比较时间;这两个UUID中包含。您需要自定义的Utility方法实现,或者只是比较两个时间戳。这是一个示例如何执行此操作:

// must be timebased UUID
int compareTo(UUID a, UUID b){
   return Long.compare(UUIDs.unixTimestamp(a),UUIDs.unixTimestamp(b));
}

要了解更多信息,请阅读此DOCS

关于Java UUID compareTo对于Type1 UUID无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60051311/

10-14 12:03
查看更多