java:UUID和雪花生成算法

目录

UUID生成不重复命名方法

在实际项目中的运用

UUID算法的缺点

什么是雪花算法?


UUID生成不重复命名方法

我们在做项目的时候可能需要用到全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID

UUID可以自动生成唯一的id。是java.util中自带的类

UUID 即统一标识符,是指能够在一台机器上生成的数字,能够保证生成的数字都是唯一的

具体的使用方法如下:

public class UuidTest {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println(uuid);
    }
}

上面程序的输出结果为:

在实际项目中的运用

此方法还可以有效地解决在项目中保存图片的问题,如果保存相同的图片就会产生覆盖的问题,解决方法就是加入此条语句对图片进行重命名,具体的使用如下(以SpringBoot项目为例):

@PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile fileUpload) {
        //获取文件名
        String fileName = fileUpload.getOriginalFilename();
      
        //获取文件后缀名。也可以在这里添加判断语句,规定特定格式的图片才能上传,否则拒绝保存。
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //为了避免发生图片替换,这里使用了文件名重新生成
        fileName = UUID.randomUUID() + suffixName;
        //打印上传相同的图片测试
        System.out.println("********"+fileName);
        try {
            // 将图片保存到文件夹里

            fileUpload.transferTo(new File(“保存到的地址”+ fileName));
           
            // 返回文件 Mapping 路径,使用 http://IP:端口/下面返回的路径 ,即可在网页中查看图片
         
            return “本地保存的地址” + fileName;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

 最终效果如下,上传相同的图片,但是不会出现重复的名字

UUID算法的缺点

但是UUID有一定的缺点:它相对较长,并且一般是无序的

有时候我们希望用一些简单的ID,并且希望ID还能够按着时间有序的生成

这就需要用到雪花算法

什么是雪花算法?

首先算法的名字本身就是Snoflake 意为雪花,世界上没有两片雪花长得一样。因此常称为雪花算法 是Twitter开源的分布式ID生成算法

Twitter雪花算法生成后是一个64bit的long型的数值,它引入了时间戳,可以实现自增

Mybatis-Plus v3.4.2 雪花算法实现类 Sequence,提供了两种构造方法:无参构造,自动生成 dataCenterId 和 workerId;有参构造,创建 Sequence 时明确指定标识位

Sequence的创建无参构造,如何生成dataCenterId 和 workerI

dataCenterId:

public static long getDataCenterId(long maxDatacenterId) {
    long id = 1L;
    final byte[] mac = NetUtil.getLocalHardwareAddress();
    if (null != mac) {
        id = ((0x000000FF & (long) mac[mac.length - 2])
                | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
        id = id % (maxDatacenterId + 1);
    }
​
    return id;
}

入参是maxDatacenterId是一个固定值 ,代表着5bit的二进制最大是11111,对应十进制数值31

dataCenterId的取值和Mvc地址有关系、

workerId:

public static long getWorkerId(long datacenterId, long maxWorkerId) {
    final StringBuilder mpid = new StringBuilder();
    mpid.append(datacenterId);
    try {
        mpid.append(RuntimeUtil.getPid());
    } catch (UtilException igonre) {
        //ignore
    }
    return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}

入参 maxWorkderId 也是一个固定值,代表工作机器 ID 最大值,默认值 31;datacenterId 取自上述的 getDatacenterId 方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ADRU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值