java uuid fasterxml_可笑!可悲!可叹!你竟然还不知道Java如何生成UUID?

一个调皮的读者在之前我写的“我去”系列文章里留言调侃说,“二哥,你是无中生小王吗?”不不不,其实真不是的,小王是真实存在的,他一直和我并肩作战,不辞辛劳,让我既爱又恨。我爱他,因为他兢兢业业,任劳任怨,和我心有灵犀;我恨他,因为他时不时会中二一下,问我一些可笑的问题,比如说这次,“二哥,你能给我说说 Java 如何生成 UUID 吗?”d619a60c3dde8f732a1ec22b1f785807.png

UUID,全名叫做 Universally Unique Identifier,也就是通用唯一标识符的意思。有时候,也叫做全局唯一标识符,英文全名叫做 Globally Unique Identifier,简拼为 GUID。

来看一下 UUID 的格式:729a521f311e22afbac06a0a88f55304.png

由四个中划线“-”隔开,第一部分的长度为 8,第二部分和第三部分的长度为 4,第四部分的长度为 12,总长度为 36,是固定的。每一部分都是一个十六进制的数字,注意并不是随机的任意字母+数字的字符串。

M 表示 UUID 的版本,N 为 UUID 的变体(Variants)。

M 的值有 5 个可选项:版本 1:UUID 是根据时间和 MAC 地址生成的;

版本 2:UUID 是根据标识符(通常是组或用户 ID)、时间和节点 ID生成的;

版本 3:UUID 是通过散列(MD5 作为散列算法)名字空间(namespace)标识符和名称生成的;

版本 4 - UUID 使用随机性或伪随机性生成;

版本 5 类似于版本 3(SHA1 作为散列算法)。

为了能兼容过去的 UUID,以及应对未来的变化,因此有了变体(Variants)这一概念。

目前已知的变体有下面 4 种:变体 0:格式为 0xxx,为了向后兼容预留。

变体 1:格式为 10xx,当前正在使用的。

变体 2:格式为 11xx,为早期微软的 GUID 预留。

变体 3:格式为 111x,为将来的扩展预留,目前暂未使用。

在上例中,M 是 1,N 是 a(二进制为 1010,符合 10xx 的格式),这就意味着这个 UUID 是“版本 1”、“变体 1”的 UUID。

目前大多数使用的 UUID 大都是变体 1,N 的取值是 8、9、a、b 中的一个。8c2f74ea4bf0109b0d73ba2acd2a778a.png

8 的二进制为 1000,9 的二进制为 1001,a 的二进制为 1010,b 的二进制为 1011,都符合 10xx 的格式。

由于 UUID 是全局唯一的,重复 UUID 的概率接近零,可以忽略不计。所以 Java 的 UUID 通常可用于以下地方:随机生成的文件名;

Java Web 应用程序的 sessionID;

数据库表的主键;

事务 ID(UUID 生成算法非常高效,每台计算机每秒高达 1000 万次)。

在 Java 中,就有一个叫 UUID 的类,在 java.util 包下。89d971a5b4e9b25c1cc9ed7b09e6cc73.png

该类只有一个构造方法:724084e0f5859c608a929110ae5d24e6.png

要使用构造方法创建 UUID 对象的话,就需要传递两个参数,long 型的最高位 UUID 和最低位的 UUID。07b11089ee43598c1ddf29abbc8b7c2a.png

输出结果如下所示:0d7d5aed7c67c16c2a0f13024f57f7a1.png

UUID 类提供了一个静态方法 randomUUID():ed4fa5356ad0f9d443f7b59d2a07399b.png

randomUUID() 方法生成了一个版本 4 的 UUID,这也是生成 UUID 最方便的方法。如果只使用原生 JDK 的话,基本上都用的这种方式。

示例如下:f919fd9766a166c01403bb9c02d7f490.png

程序输出结果如下所示:7c4a145d8c7dba4405acaed1f8948194.png

除此之外,UUID 类还提供了另外两个静态方法,其一是 nameUUIDFromBytes():b95c4f2cb5e8e21fdc043b13f30b6153.png

nameUUIDFromBytes() 会生成一个版本 3 的 UUID,不过需要传递一个名称的字节数组作为参数。

示例如下:004371eff21417c9b2e9fbadc417dd10.png

程序输出结果如下所示:287bc795486b279b568e688a91910d65.png

其二是 fromString():2296249cb607cd7ce9cbaa90b7199876.png

fromString() 方法会生成一个基于指定 UUID 字符串的 UUID 对象,如果指定的 UUID 字符串不符合 UUID 的格式,将抛出 IllegalArgumentException 异常。

示例如下:3425ee04609a430adef8d80491076d36.png

程序输出结果如下所示:ecb1f89b716674f35182cd94ba2025ae.png

除了使用 JDK 原生的 API 之外,还可以使用 com.fasterxml.uuid.Generators,需要先在项目中加入该类的 Maven 依赖。326d33df41b0c2556b3b36374307c3a3.png

然后我们来看一下如何使用它:9a043a553d1b2b7f22a9e08d360a73d6.png

Generators.timeBasedGenerator().generate() 可用于生成版本 1 的 UUID,Generators.randomBasedGenerator().generate() 可用于生成版本 4 的 UUID。

来看一下输出结果:fc1b4179bcd1f5b5f2aa39a48e9a4507.png

好了,我想关于 UUID 的一切,我都已经说明白了。赶紧把这篇文章先发给小王预览一下,让他涨涨见识。作者:沉默王二

链接:https://juejin.im/post/6856187633660493832

来源:掘金

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值