Java通过UUID生成16位唯一订单号

小编在工作中遇到了标题中的场景,先查了一些微博,参考下大佬经验。最终发现大家写的都是一套代码,没有太多的信息量做对比,并且UUID的hashcode值重复的概率有多大问题,没有人给解释。小编根据自己经验,结合业务实际,对16编码总结了下,希望对你会有帮助。

网络上的写法:

    public static void get16UUID(){
        // 1.最大支持1-9个集群机器部署
        int machineId = 1;
        // 2.生成uuid的hashCode值
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        // 3.有可能是负数
        if(hashCodeV < 0) {
            hashCodeV = - hashCodeV;
        }
        // 4.结果
        String value =  machineId + String.format("%015d", hashCodeV);
        System.out.println(value);
        }
    }

以上代码的缺点:

通过我的研究和实践,发现UIID的hashcode值可能为9位或10位,但不超过10位。所以,String.format("%015d", hashCode)算法会在hashcode值前补至少5个无意义的0,属于占着茅坑不拉屎的角色,实在是对仅有的16位编码的位置浪费。小编的做法,是补全至10位,将前6位充分利用,不仅要达到进一步降低重复概率的目的,还要增强编码的可读性。

我的写法:

    public static void get16UUID(){
        // 1.开头两位,标识业务代码或机器代码(可变参数)
        String machineId = 11;
        // 2.中间四位整数,标识日期
        SimpleDateFormat sdf = new SimpleDateFormat("MMdd");
        String dayTime = sdf.format(new Date());
        // 3.生成uuid的hashCode值
        int hashCode = UUID.randomUUID().toString().hashCode();
        // 4.可能为负数
        if(hashCode < 0){
            hashCode = -hashCode;
        }
        // 5.算法处理: 0-代表前面补充0; 10-代表长度为10; d-代表参数为正数型
        String value = machineId + dayTime + String.format("%010d", hashCode);
        System.out.println(value);
    }

    结果示例:1110242019091420

原则:不改变核心代码

算法:业务代码 + 日期 + HashCode值

目的:进一步降低编码重复概率的同时,增强其可读性,使其具备一定的业务含义

其中,第二步对中间四位的操作,也可使用四位随机数代替,如下:

        ......
        // 2.生成四位随机整数
        int valueOf = (int)((Math.random()*9+1)*1000);
        ......
        // 5.算法处理: 0-代表前面补充0; 10-代表长度为10; d-代表参数为正数型
        String value = machineId + valueOf + String.format("%010d", hashCode);
        ......

建议:

对于UUID的hashcode值,小编亲测并发运行100万次无重复。实际开发中,再加上机器代码、业务代码、日期,估计重复可能只能存在于理论层面了。

即便如此,还是废一句很必要的话:在存储数据的时候,还是建议先判断一下主键是否存在,不要嫌麻烦。

 

更多精彩,请关注我的"今日头条号":Java云笔记
随时随地,让你拥有最新,最便捷的掌上云服务

你可能感兴趣的:(《Java从入门到精通》)