Java UUID详解

UUID是通用唯一标识符的缩写,是一个软件构建的标准,它使用长度为128位(16字节)的值来表示信息。UUID可以保证对在同一时空中的所有机器都是唯一的,它实际上上是利用网络上的时间和计算机MAC地址来生成的。

一、UUID的优点

1、全球唯一性

    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
    System.out.println(uuid);

UUID采用128位编码,标识信息的唯一性,长时间不重复,保证了对于海量数据处理时,不会产生冲突。

2、无序性

    UUID uuid1 = UUID.randomUUID();
    UUID uuid2 = UUID.randomUUID();
    System.out.println(uuid1.compareTo(uuid2));

UUID采用无序性的编码,这个特性可以避免数据库在写入数据时,需要枷锁和解锁的操作,显著提升了开发效率。

3、方便存储和传输

    UUID uuid = UUID.randomUUID();
    ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
    buffer.putLong(uuid.getMostSignificantBits());
    buffer.putLong(uuid.getLeastSignificantBits());
    byte[] array = buffer.array();

UUID仅使用128位,方便对任意平台和数据库进行数据存储和传送。

二、UUID的使用

1、获取UUID

    UUID uuid = UUID.randomUUID();
    System.out.println(uuid.toString());

UUID类提供了randomUUID()方法,可以用于获取一个UUID对象。

2、UUID的表示

    UUID uuid = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
    System.out.println(uuid.getLeastSignificantBits());

通过fromString()方法可以将字符串转化成UUID对象,其中的连字符是可选的,但建议保留,这样可以方便读取。

3、UUID的比较

    UUID uuid1 = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
    UUID uuid2 = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
    System.out.println(uuid1.equals(uuid2));

UUID类提供了equals()、compareTo()等方法,用于比较两个UUID的大小是否相等,或者两个UUID是否相等,如果相等则返回0。

三、UUID生成算法

1、时间戳

    private static long toUnixTime(long timeStamp) {
        return (timeStamp - START_EPOCH) * 10000 + 0x01b21dd213814000L;
    }

    private static long timeToMillis(long time) {
        return (time - 0x01b21dd213814000L) / 10000 + START_EPOCH;
    }

    private static final long START_EPOCH;

    static {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        calendar.set(1582, Calendar.OCTOBER, 15, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        START_EPOCH = calendar.getTimeInMillis();
    }

    private static long createTimestamp() {
        long timestamp = System.currentTimeMillis();
        long time = toUnixTime(timestamp);
        return time;
    }

UUID生成的过程中,会生成一个时间戳,通过时间戳可以保证生成的UUID在不同时间生成时不会重复。在Java中,可以使用System.currentTimeMillis()方法获取一个毫秒级别的时间戳。

2、MAC地址

    private static long createNode() {
        InetAddress address;
        try {
            address = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
        byte[] mac = null;
        try {
            mac = NetworkInterface.getByInetAddress(address).getHardwareAddress();
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
        if (mac == null) {
            return 0xffffffffffffL;
        }
        long node = 0;
        for (int i = 0; i < mac.length; i++) {
            node |= ((long) mac[i] & 0xff) << (8 * (5 - i));
        }
        return node;
    }

UUID生成的过程中,还会用到机器的MAC地址,通过MAC地址可以保证生成的UUID在同一时间内,在不同机器上也不会重复。

3、随机数

    private static long createRandom() {
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[8];
        random.nextBytes(bytes);
        return ((long) bytes[0] & 0xff) << 56 |
                ((long) bytes[1] & 0xff) << 48 |
                ((long) bytes[2] & 0xff) << 40 |
                ((long) bytes[3] & 0xff) << 32 |
                ((long) bytes[4] & 0xff) << 24 |
                ((long) bytes[5] & 0xff) << 16 |
                ((long) bytes[6] & 0xff) << 8 |
                ((long) bytes[7] & 0xff);
    }

UUID生成的过程中,还会用到随机数,通过随机数的存在,可以保证生成的UUID的唯一性。

四、UUID的应用场景

1、主键

在数据库中,通常将主键设计成UUID,可以避免业务层和数据层之间的耦合,更容易扩展。

2、文件名

在上传文件时,可以将文件名设置成UUID,可以避免出现重名文件,而且易于管理。

3、网络通信

在分布式系统中,可以使用UUID来定义一致的消息格式,方便不同系统之间的通信。

五、总结

UUID是一个通用唯一标识符,具有全球唯一性、无序性、方便传输等优点,可以应用于主键、文件名、网络通信等场景。UUID的生成需要时间戳、MAC地址和随机数的支持,可以采用UUID类提供的方法获取UUID对象,也可以自己编写生成算法。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/303860.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-31 11:50
下一篇 2024-12-31 11:50

相关推荐

  • java client.getacsresponse 编译报错解决方法

    java client.getacsresponse 编译报错是Java编程过程中常见的错误,常见的原因是代码的语法错误、类库依赖问题和编译环境的配置问题。下面将从多个方面进行分析…

    编程 2025-04-29
  • Java JsonPath 效率优化指南

    本篇文章将深入探讨Java JsonPath的效率问题,并提供一些优化方案。 一、JsonPath 简介 JsonPath是一个可用于从JSON数据中获取信息的库。它提供了一种DS…

    编程 2025-04-29
  • Java Bean加载过程

    Java Bean加载过程涉及到类加载器、反射机制和Java虚拟机的执行过程。在本文中,将从这三个方面详细阐述Java Bean加载的过程。 一、类加载器 类加载器是Java虚拟机…

    编程 2025-04-29
  • Java腾讯云音视频对接

    本文旨在从多个方面详细阐述Java腾讯云音视频对接,提供完整的代码示例。 一、腾讯云音视频介绍 腾讯云音视频服务(Cloud Tencent Real-Time Communica…

    编程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介绍

    本文将详细介绍Java Milvus SearchParam withoutFields的相关知识和用法。 一、什么是Java Milvus SearchParam without…

    编程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java语言中的一个版本,于2014年3月18日发布。本文将从多个方面对Java 8中某一周的周一进行详细的阐述。 一、数组处理 Java 8新特性之一是Stream…

    编程 2025-04-29
  • Java判断字符串是否存在多个

    本文将从以下几个方面详细阐述如何使用Java判断一个字符串中是否存在多个指定字符: 一、字符串遍历 字符串是Java编程中非常重要的一种数据类型。要判断字符串中是否存在多个指定字符…

    编程 2025-04-29
  • VSCode为什么无法运行Java

    解答:VSCode无法运行Java是因为默认情况下,VSCode并没有集成Java运行环境,需要手动添加Java运行环境或安装相关插件才能实现Java代码的编写、调试和运行。 一、…

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29
  • Java 8 Group By 会影响排序吗?

    是的,Java 8中的Group By会对排序产生影响。本文将从多个方面探讨Group By对排序的影响。 一、Group By的概述 Group By是SQL中的一种常见操作,它…

    编程 2025-04-29

发表回复

登录后才能评论