java - 为什么两个不同的 java.util.UUID 对象比较相等?

标签 java uuid

我创建了两个 java.util.UUID 实例,如下所示。一个是从 UUID.randomUUID() 创建的,另一个是相同的,但在开头添加了一些额外的数字。当使用 UUID.equals 方法比较它们时,它返回 true:

UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.fromString("12345"+uuid1.toString());
System.out.println(uuid1.equals(uuid2));  // this gives true.

我认为添加的数字被丢弃了,并且都给出了相同的 UUID 字符串值。为什么会这样?

最佳答案

在 UUID.fromString(...) 方法中你有这个:

public static UUID fromString(String name) {
    String[] components = name.split("-");
    if (components.length != 5)
        throw new IllegalArgumentException("Invalid UUID string: "+name);
    for (int i=0; i<5; i++)
        components[i] = "0x"+components[i];

    long mostSigBits = Long.decode(components[0]).longValue();
    mostSigBits <<= 16;
    mostSigBits |= Long.decode(components[1]).longValue();
    mostSigBits <<= 16;
    mostSigBits |= Long.decode(components[2]).longValue();

    long leastSigBits = Long.decode(components[3]).longValue();
    leastSigBits <<= 48;
    leastSigBits |= Long.decode(components[4]).longValue();

    return new UUID(mostSigBits, leastSigBits);
}

它做的第一件事是将 UUID 的各个部分分成组件,然后它会创建两个 long。在这里,您通过添加前导字符仅更改了 UUID 的第一个组件,您的 UUID 字符串例如为“12345894ff97a-039b-47fe-8a72-950b7766d50c”。所以第一个组件是“12345894ff97a”,什么时候会做

long mostSigBits = Long.decode(components[0]).longValue();

然后你会得到“320256540146042”,实际的十六进制表示是“12345894ff97a”,然后你有一个位操作,将长 16 位向左移动:

mostSigBits <<= 16;

这将导致“2541588541301456896”,实际的十六进制表示为“2345894ff97a0000”(我们移动了 16 位,所以 4 个十六进制字符),您开始看到发生了什么,看到长格式是只有 64 位,所以在移动位时会丢失一些,这里第一个字符“1”丢失了。之后,在释放的空间中,它将添加第二个组件:

mostSigBits |= Long.decode(components[1]).longValue();

这将导致“2541588541301457819”,实际的 HEX 表示为“2345894ff97a039b”,然后它将长 16 位再次向左移动:

mostSigBits <<= 16;

这将导致“-8552342864911466496”,实际的 HEX 表示为“894ff97a039b0000”,由于 64 位长,这里您的前导字符全部丢失。

剩下的方法不用我解释了(最后 mostSigBits 是 "894ff97a039b47fe"leastSigBits 是 "8a72950b7766d50c"),你已经明白了,任何添加到 UUID 的前导字符在调用 UUID 时都会丢失.fromString(..) 因为只考虑最后 8 个十六进制字符(32 位),其余的将丢失。

关于java - 为什么两个不同的 java.util.UUID 对象比较相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44518355/

相关文章:

ruby-on-rails - Rails Digest::UUID v5 (vs) Postgresql uuid-ossp v5

ios - 在某些情况下,UUID 是否会发生变化

java - 在 Eclipse Indigo 上安装新的 Glassfish 服务器

java - 获取范围内所有基站的 CID、LAC 和信号强度

java - 如何在 Spring-Boot 的生产过程中覆盖 application.properties?

python - 防止Python同一进程中uuid冲突

java - 为什么日期选择器会意外触发 JComboBox 的 actionPerformed?

java - 使用特定版本的 JRE 执行 JAR 文件

ios - 如何快速生成设备特定的唯一uuid

java - 从字符串生成的 UUID 是否可逆?