当前位置: 首页 > 知识库问答 >
问题:

Java UUID比较对于类型1 UUID无法正常工作

宰父劲
2023-03-14

在处理一个用例时,数据需要在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驱动程序生成了下面两个UUIDs。

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的排序?

非常感谢。

共有1个答案

余歌者
2023-03-14

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

最后,请注意,Cassandra 的 timeuuid 排序与 UUID.compareTo(java.util.UUID) 不兼容,因此此方法创建的 UUID 不一定是后一种方法的下限。

基于时间的UUID不应与< code > Java . util . uuid # compare to 进行比较。要比较两个基于时间的UUID,你应该比较时间;在这两个UUID包含。您需要一个定制的实用方法实现,或者只比较两个时间戳。下面是一个如何做到这一点的例子:

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

要了解更多信息,请浏览此 DOCS。

 类似资料:
  • 问题内容: 我的代码: 引用的日志文件是: 然后,需要检查脚本中的下一个条件是: 如果条件不起作用 问题答案: 必要的修复: 此后已在问题中解决。 可能必要的修复: 如注释中所述,在脚本中使用尾随空格表示将尾随空格存储在其中,这将破坏与的比较。

  • 问题内容: 在ajax中使用base_url()从codeigniter项目中获取数据库。给定的base_url就像http://domainname.com。很好 如果我可以在地址栏中输入http://www.domainname.com之类的网址,则无法正常工作。该代码是 请帮助解决此问题。谢谢 问题答案: 我认为最好的解决方案是: 只需在HTML的标头部分中添加以下脚本即可。 然后在您的Aj

  • 根据https://developers.facebook.com/docs/messenger-platform/send-api-reference/video-attachment我应该可以通过信使发送视频。理想情况下,我想发送带有开始和结束时间的youtube视频,但这似乎行不通。 我目前正试图让它以任何这样的方式工作,所以我目前在FB上有视频,甚至那是不工作的。 python代码 201

  • 我正在将边添加到PriorityQueue,但由于某些原因,它们没有按其值进行排序,从而导致以后出现错误的结果。 我的边缘班是这样的 然而,当我运行我的代码,在属于节点“Springfield,MO”的LinkedList中将所有内容添加到PriorityQueue时,边按错误的顺序排序,如下图所示,问题是什么? 我尝试为Edge创建一个特定的比较器类,并将其用作PriorityQueue中的参数

  • 问题内容: 我需要编写一个比较器,它采用类型A的对象A和类型B的对象B。这两个对象不是公共对象的扩展。它们的确不同,但是我需要通过其中的通用字段来比较这两个对象。我必须使用比较器接口,因为对象存储在Set中,并且在必须对CollectionUtils执行操作之后。我在Google上搜索了一下,发现了Comparator的解决方案,但只有相同的类型。 我试图朝这个方向实施思考,但是我不知道我是否在正

  • 我需要写一个比较器,取一个a类型的对象a和一个B类型的对象B。这两个对象不是一个公共对象的扩展。他们确实是不同的,但我需要比较这两个对象在它的共同领域。我必须使用比较器接口,因为对象存储在Set中,之后我必须使用CollectionUtils进行操作。我搜索了一点点,我用比较器找到了解决方案,但只有相同的类型。 TXS 附注:我在不同的集合中添加两个对象: 之后我会这样想: