如何使用UUID生成唯一正Long

时间:2013-03-03 10:43:45

标签: java uuid

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

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

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

4 个答案:

答案 0 :(得分:26)

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

这样做的原因是,当你按位进行操作时使用1,它允许相同的数字通过,当你按位和按下时0表示阻塞,结果为0.现在,二进制的Long.MAX_Value为

0111111111111111111111111111111111111111111111111111111111111111 

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

所以当你按位&如果数字为X,那么您将得到相同的数字X,除了最左边的位现在变为零。这意味着您只更改了该数字的符号而不是值。

答案 1 :(得分:7)

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

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

nano&amp; 〜9223372036854251520L 部分取当前纳秒并将前44个字节设置为0,只留下右边的20位,表示纳秒,最长为1毫秒(999999纳米) 它与:

相同
nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000

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

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

答案 2 :(得分:5)

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

答案 3 :(得分:2)

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

https://github.com/Predictor/javasnowflake

欢迎任何建议。

相关问题