java唯⼀字符串ID⽣成⽅案详解
⼯作中经常会有⽣成唯⼀字符串的需求。通常最容易想到的是UUID。UUID的唯⼀性⽏庸置疑,但是32位的长度也容易让⼈退避三舍。也曾经想过参考《》来⽣成⼀串ID,但是试验了⼀下发现唯⼀性不太好。
最终采⽤的⽅案是时钟⽅案,简单来说就是⽤当前时间戳做唯⼀ID。
采⽤时间戳做ID,秒或毫秒都容易产⽣重复,换成纳秒在单节点上就没问题了。参考百度百科关于纳秒的描述就能清楚为什么纳秒级别的时间戳不会产⽣重复:
光在真空中⼀纳秒仅传播0.3⽶。个⼈电脑的微处理器执⾏⼀道指令(如将两数相加)约需2⾄4纳秒。
我们⽣成⼀条唯⼀ID所需的CPU指令绝不⽌⼀道,因此⽤纳秒作单机唯⼀ID是绰绰有余的。在测试中发现,即使是千分之⼀纳秒也⾜够我们在PC机上⽣成唯⼀ID了。
⾄于长度:对原始值做⼀次Base62处理,长度就能缩减到令⼈满意的程度。
不多废话,直接上代码:
public static synchronized String gen() {
StringBuilder builder = new StringBuilder(System.nanoTime() / 1000 + "");
if (SEQ.incrementAndGet() % 10 == 0) {
SEQ.incrementAndGet();
}
builder.append(FORMAT.()));
if ((MAX_PAD_SIZE - 1) == ()) {
SEQ.set(1);
}
long v = Long.verse().toString());
de(v);
}
这⾥⽤千分之⼀纳秒做基数(经测试,基数在10w分之⼀纳秒内都是安全的),再加上1~99的顺序号来⽣成唯⼀ID。最终可以保证在⼤于10纳秒(近似)的时间区间内不会产⽣重复值。
为了缩减长度,对字符串做了 Base62处理。在处理前⼜将纳秒数值做了⼀次翻转处理。不难想象,如果直接使⽤原始值来做Base62处理,因为时钟的特征,最终⽣成的值的前⼏位都是相同的。
来看⼀下这个程序⽣成的ID:
aSPog4cC
d4t1xZdt
g2tkZVqv
jrinwXx5
m8ZIAKVr
oUB5nzS5
rZa1gPAl
uD12VZ3A
8dnItkTj
⼋位的长度,唯⼀且整齐。下⾯是⼀个单元测试:
@Test
public void gen() {
int size = 10240;
Set<String> set = new HashSet<>();
for (int i = 0; i < size; i++) {
String code = ();
//System.out.println(code);
set.add(code);
}
Assert.assertEquals(size, set.size());
}
java技术介绍百度百科
这⾥只对10240的规模做了测试。因为唯⼀ID是基于时钟⽣成的,所以测试时整体规模的⼤⼩不影响ID的唯⼀性(和短链接⽅案不⼀样)。但是太⼩了也不⾏——顺序号会发挥作⽤。10240算是⼀个中庸的值,⾜够暴露问题,也不会有太多的冗余。
仍然需要强调⼀下:这个⽅案只能保证在(当前)单机上的唯⼀性,如果是集范围内建议采⽤其他⽅案,或者加上⼀两位机器ID。
总结
到此这篇关于java唯⼀字符串ID⽣成⽅案的⽂章就介绍到这了,更多相关java唯⼀字符串ID⽣成内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。