gpt4 book ai didi

Java UUID CompareTo 对于 Type1 UUID 无法正常工作

转载 作者:行者123 更新时间:2023-12-02 20:03:05 25 4
gpt4 key购买 nike

在处理需要对 UUID 上的数据进行排序的用例时,这些数据都是类型 1 或基于时间的,并使用 Datastax Cassandra Java 驱动程序库 (UUIDS.timebased()) 生成,我发现 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 小,但是当我们使用 UUIDcompareTo 方法比较它们时,我们得到不同的输出。我们应该得到输出为 -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 :

Lastly, please note that Cassandra's timeuuid sorting is not compatible with UUID.compareTo(java.util.UUID) and hence the UUID created by this method are not necessarily lower bound for that latter method.

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

// 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com