如何使用UUID生成唯一的Long

我需要为我的数据库主键列生成唯一的Long ID。

我以为我可以使用UUID.randomUUID()。getMostSignificantBits(),但有时它会产生一些负长,这对我来说也是个问题。

是否有可能只从UUID生成正长?会有数十亿条目,所以我希望每个生成的密钥必须是唯一的。

看看http://commons.apache.org/sandbox/commons-id//index.html它有一个LongGenerator,它可以满足您的需求。

此外,如果您正在使用Hibernate,那么您可以要求它为您生成ID(它有多种算法供您选择),如果不是,您可以查看它们的实现,例如http://grepcode.com/ file / repo1.maven.org / maven2 / hibernate / hibernate / 2.1.8 / net / sf / hibernate / id / TableHiLoGenerator.java#TableHiLoGenerator )

UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE 

这样做的原因是,当你按位并且使用1时,它允许相同的数字传递,当你按位时,按0并阻塞它,结果为0.现在,二进制的Long.MAX_Value是

 0111111111111111111111111111111111111111111111111111111111111111 

这是0然后是63 1s(总共是64位,它在java中很长)

因此,当你按位数和带有上述数字的数字X时,你将获得相同的数字X,除了最左边的位现在变为零。 这意味着您只更改了该数字的符号而不是值。

正如其他人所写,长期没有足够的空间来存放唯一的数字。 但在许多情况下,对于特定用途,数字可能是唯一的。 例如,具有纳秒精度的时间戳通常足够好。 为了得到它,将当前毫秒20位移位以分配空间纳秒,然后用纳秒覆盖它:

 (System.currentTimeMillis() << 20) | (System.nanoTime() & ~9223372036854251520L); 

nano&〜9223372036854251520L部分采用当前纳秒并将前44个字节设置为0,仅留下右边20位,表示纳秒,最长为1毫秒(999999纳米)。它与以下内容相同:

 nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000 

旁注:纳秒不应用于表示当前时间,因为它们的起点不是及时固定的,因为它们在达到最大值时会被回收。

您可以使用任何其他位操作。 考虑当前时间和其他内容(例如当前线程ID,进程ID,ip)通常是好的。

我刚刚遇到了这个解决方案。 我暂时试图理解解决方案。它说Java雪花的Java实现。 基于twitter雪花ID生成算法的64位顺序ID生成器。

https://github.com/Predictor/javasnowflake

欢迎任何建议。