Java:唯一的 10 位 ID

2022-09-03 07:23:40

我需要在Java中生成一个唯一的10位ID。以下是此 ID 的限制:

  • 仅数字
  • 最多 10 位数字
  • 每秒最多可创建 10 个不同的 ID
  • 必须是唯一的(即使应用程序重新启动)
  • 无法在数据库中保存数字
  • 尽可能快地不给系统增加太多的乳化度

到目前为止,我发现的最佳解决方案如下:

private static int inc = 0;

private static long getId(){

    long id = Long.parseLong(String.valueOf(System.currentTimeMillis())
            .substring(1,10)
            .concat(String.valueOf(inc)));
    inc = (inc+1)%10;
    return id;
}

此解决方案存在以下问题:

  • 如果出于任何原因需要每秒创建超过 10 个 ID,则此解决方案将不起作用。
  • 在大约32年内,这个ID可以重复(这可能是可以接受的)

创建此 ID 的任何其他解决方案?

还有其他问题我没有想到吗?

感谢您的帮助,


答案 1

这是你的一个小增强,但应该是弹性的。

从本质上讲,我们使用当前时间(以毫秒为单位),除非它自上次id以来没有滴答作响,在这种情况下,我们只返回。last + 1

private static final long LIMIT = 10000000000L;
private static long last = 0;

public static long getID() {
  // 10 digits.
  long id = System.currentTimeMillis() % LIMIT;
  if ( id <= last ) {
    id = (last + 1) % LIMIT;
  }
  return last = id;
}

因此,它应该以相对较短的周期速率管理高达每秒1000次。要延长循环速率(但缩短分辨率),可以使用 或 。(System.currentTimeMillis() / 10) % 10000000000L(System.currentTimeMillis() / 100) % 10000000000L


答案 2

这可能是一个疯狂的想法,但它是一个:)的想法。

  • 首先生成 UUID 并获取其字符串表示形式java.util.UUID.randomUUID().toString()
  • 第二次将生成的字符串转换为字节数组 (byte[])

  • 然后将其转换为长缓冲区:java.nio.ByteBuffer.wrap( byte digest[] ).asLongBuffer().get()

  • 截断为 10 位数字

我不确定这种方法的唯一性,我知道你可以依靠UUID的唯一性,但还没有检查它们转换和截断为10位数字的唯一性。

示例取自JavaRanch,也许还有更多。

编辑:由于您被限制为10位数字,也许简单的随机生成器对您来说就足够了,因此请在SO:Java:0 <= x <n范围内查看该问题/答案