首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Java中生成唯一的长整型

问如何在Java中生成唯一的长整型
EN

Stack Overflow用户
提问于 2021-02-20 22:36:40
回答 2查看 111关注 0票数 1

我正在尝试生成唯一的数字in,作为Mysql数据库中的主键。由于系统的分布式特性,我需要在数据库之外生成它们。

这是我的尝试:

代码语言:javascript
复制
@RunWith(MockitoJUnitRunner.class)
public class AbstractEntityTest {

    @Test
    public void testGenerateUniqueId() {

        val ids = new HashSet<Long>();
        val duplicates = new HashSet<Long>();
        for (int i = 0; i < 1000000; i++) {
            val id = System.currentTimeMillis() +
                    (ThreadLocalRandom.current().nextLong(9999999) + ThreadLocalRandom.current().nextLong(9999999));
            if (!ids.add(id)) {
                duplicates.add(id);
            }
        }

        System.out.println("ids: " + ids.size());
        System.out.println("Duplicates: " + duplicates.size());
        assertThat(duplicates).isEmpty();
    }
}

结果是:

代码语言:javascript
复制
ids: 967265
Duplicates: 31939

有没有人建议用Java语言生成真正唯一的long的更好的方法?

一个解决方案似乎是:

代码语言:javascript
复制
@Test
    public void testGenerateUniqueId_withUUID() {

        val ids = new HashSet<Long>();
        val duplicates = new HashSet<Long>();
        for (int i = 0; i < 1000000; i++) {
            val id = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE;
            if (!ids.add(id)) {
                duplicates.add(id);
            }
        }

        System.out.println("ids: " + ids.size());
        System.out.println("Duplicates: " + duplicates.size());
        assertThat(duplicates).isEmpty();
    }

结果是:

代码语言:javascript
复制
ids: 1000000
Duplicates: 0

下面是3,000万代的5次迭代:

代码语言:javascript
复制
@Test
    public void testGenerateUniqueId_withUUID() {

        val iterations = 5;

        for (int j = 0; j < iterations; j++) {
            val ids = new HashSet<Long>();
            val duplicates = new HashSet<Long>();
            for (int i = 0; i < 30000000; i++) {
                val id = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE;
                if (!ids.add(id)) {
                    duplicates.add(id);
                }
            }

            System.out.println(String.format("Iteration %s of %s", j + 1, iterations));
            System.out.println("ids: " + ids.size());
            System.out.println("Duplicates: " + duplicates.size());
            assertThat(duplicates).isEmpty();
        }
    }

结果是:

代码语言:javascript
复制
Iteration 1 of 5
ids: 30000000
Duplicates: 0
Iteration 2 of 5
ids: 30000000
Duplicates: 0
Iteration 3 of 5
ids: 30000000
Duplicates: 0
Iteration 4 of 5
ids: 30000000
Duplicates: 0
Iteration 5 of 5
ids: 30000000
Duplicates: 0

我添加了以毫秒为单位的当前时间,以帮助在运行的进程之外实现唯一性。

代码语言:javascript
复制
@Test
    public void testGenerateUniqueId_withUUID_andCurrentTimeMilliseconds() {

        val iterations = 5;

        val duplicates = new HashSet<Long>();
        for (int j = 0; j < iterations; j++) {
            val ids = new HashSet<Long>();
            for (int i = 0; i < 30000000; i++) {
                val id = System.currentTimeMillis() + UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE;
                if (!ids.add(id)) {
                    duplicates.add(id);
                }
            }

            System.out.println(String.format("Iteration %s of %s", j + 1, iterations));
            System.out.println("ids: " + ids.size());
            System.out.println("Duplicates: " + duplicates.size());
            assertThat(duplicates).isEmpty();
        }
    }
EN

回答 2

Stack Overflow用户

发布于 2021-02-20 22:47:18

如果可能,我建议您切换到UUID,我认为它更适合您的目的。使用UUID,您只需执行以下操作:

代码语言:javascript
复制
UUID uuid = UUID.randomUUID();
票数 1
EN

Stack Overflow用户

发布于 2021-02-20 22:48:15

考虑到UUID几乎是唯一的,您可以使用UUID并将其转换为long

代码语言:javascript
复制
long uniqueNum = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE

如果您想保持唯一性,并且可以将id转换为字符串,那么您可以使用

代码语言:javascript
复制
String uniqueId = UUID.randomUUID().toString();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66292730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档