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

时间:2017-06-13 10:05:58

标签: 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字符串值。为什么会这样?

2 个答案:

答案 0 :(得分:4)

在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字符串例如是“ 12345 894ff97a-039b-47fe-8a72-950b7766d50c”。所以第一个组件是“ 12345 894ff97a”,什么时候会这样做

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

然后你会得到“320256540146042”,实际的HEX表示是“ 12345 894ff97a”,然后你有一个位操作,将长16位向左移位:

mostSigBits <<= 16;

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

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

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

mostSigBits <<= 16;

这将导致“-8552342864911466496”,其实际HEX表示为“894ff97a039b0000”,此处您的前导字符全部丢失,因为长64位大小。

我不需要解释方法的其余部分(最后,大多数位置是“894ff97a039b47fe”,而最小位置是“8a72950b7766d50c”),您已经可以理解,在调用UUID时,添加到UUID的任何前导字符都将丢失.fromString(..)因为只考虑最后8个十六进制字符(32位),其余的将会丢失。

答案 1 :(得分:0)

因为您没有创建两个不同的UUID。

UUID.fromString("12345"+uuid1.toString());没有意义:UUID.fromString(String)要求传递的String遵守UUID.toString()中描述的'字符串标准表示'。请参阅UUID.fromString()UUID.toString()

我想知道为什么你不会得到例外,但我想你的前几个字符会被忽略。