Formas comunes para que Java genere UUID

  1. Clase java.util.UUID para generar UUID

import java.util.UUID;

public class UUIDGenerator {
    
    
    public static void main(String[] args) {
    
    
        
        //随机生成一个UUID对象
        UUID uuid = UUID.randomUUID();
        System.out.println("生成的UUID为:" + uuid.toString());
        
        //通过给定的字符串名称和命名空间生成UUID对象
        UUID uuid2 = UUID.nameUUIDFromBytes("example_name".getBytes());
        System.out.println("生成的UUID2为:" + uuid2.toString());
    }
}
/*优点:
Java自带,无需引入额外的库和依赖;
简单易用,一行代码就可以生成UUID。

缺点:
生成的UUID可能会重复,虽然重复的概率较小,但是在高并发的情况下还是有可能发生;
无法控制生成的UUID的格式,只能生成标准的UUID*/

  1. La clase UUIDUtils en la biblioteca Apache Commons IO

import org.apache.commons.io.UUIDUtils;

public class UUIDGenerator {
    
    
    public static void main(String[] args) {
    
    
        
        //随机生成一个UUID字符串
        String uuid = UUIDUtils.randomUUID().toString();
        System.out.println("生成的UUID为:" + uuid);
    }
}
/*
三方库优缺点
优点:
可以生成唯一的UUID;
很多开源库和框架都提供了UUID生成的支持。

缺点:
会增加项目的依赖和复杂度;
不同的库实现方式不同,可能会影响生成的UUID的格式和唯一性。
*/
  1. Genere UUID utilizando la clase UUIDGenerator de la biblioteca Google Guice

import com.google.inject.Inject;
import com.google.inject.name.Named;
import java.util.UUID;

public class UUIDGenerator {
    
    
    private final UUID uuid;

    @Inject
    public UUIDGenerator(@Named("randomUUID") UUID uuid) {
    
    
        this.uuid = uuid;
    }

    public UUID getUUID() {
    
    
        return uuid;
    }
    
    public static void main(String[] args) {
    
    
        UUIDGenerator generator = new UUIDGenerator(UUID.randomUUID());
        System.out.println("生成的UUID为:" + generator.getUUID().toString());
    }
}

  1. Use la clase MessageDigest de JDK y la clase SecureRandom: el UUID puede generarse mediante el algoritmo Hash y el número aleatorio

写法一:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;

public class UUIDGenerator {
    
    
    public static void main(String[] args) throws NoSuchAlgorithmException {
    
    
        SecureRandom secureRandom = new SecureRandom();
        byte[] seed = secureRandom.generateSeed(16);
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(seed);
        UUID uuid = UUID.nameUUIDFromBytes(md5.digest());
        System.out.println("生成的UUID为:" + uuid.toString());
    }
}
写法二:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

public class UUIDGenerator {
    
    

    public static String generateUUID() {
    
    
        String result = "";
        try {
    
    
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest((System.currentTimeMillis() + new Random().nextInt(99999999) + "").getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : messageDigest) {
    
    
                sb.append(String.format("%02x", b));
            }
            result = sb.toString();
        } catch (NoSuchAlgorithmException e) {
    
    
            e.printStackTrace();
        }
        return result;
    }

}

/*
优点:
可以通过Hash算法和随机数生成唯一的UUID,具有较高的唯一性;
实现简单,无需引入额外的库和依赖。

缺点:
重复的概率比较难以预测,取决于生成的Hash值的分布情况;
无法控制生成的UUID的格式,只能生成基于MD5或SHA-1的UUID。
*/

  1. Generar UUID utilizando el algoritmo Snowflake

El algoritmo Snowflake es el algoritmo de generación de ID distribuido de código abierto de Twitter, que puede generar ID únicos en múltiples nodos.

import com.github.f4b6a3.uuid.UuidCreator;
import com.github.f4b6a3.uuid.enums.UuidVariant;
import com.github.f4b6a3.uuid.enums.UuidVersion;
import com.github.f4b6a3.uuid.impl.TimeBasedUuidCreator;

import java.time.Instant;

public class UUIDGenerator {
    
    
    public static void main(String[] args) {
    
    
        UuidCreator creator = TimeBasedUuidCreator.withRandomNodeId();
        Instant now = Instant.now();
        long timestamp = now.getEpochSecond() * 1000 + now.getNano() / 1000000;
        String uuid = creator.create(UuidVersion.VERSION_TIME_BASED, timestamp).toString();
        System.out.println("生成的UUID为:" + uuid);
    }
}
/*
优点:
可以在分布式系统中生成唯一的ID,具有较高的唯一性和可读性;
可以控制生成的ID的格式和信息。

缺点:
实现相对复杂,需要实现一个全局唯一的时钟服务;
只适用于分布式系统,不适用于独立的单机系统。
*/

El segundo algoritmo de copo de nieve:

public class UUIDGenerator {
    
    

    /** 开始时间截 (2017-01-01) */
    private final long twepoch = 1483200000000L;
    /** 机器id所占的位数 */
    private final long workerIdBits = 5L;
    /** 数据标识id所占的位数 */
    private final long datacenterIdBits = 5L;
    /** 支持的最大机器id,结果是31 */
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    /** 支持的最大数据标识id,结果是31 */
    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    /** 序列在id中占的位数 */
    private final long sequenceBits = 12L;
    /** 机器ID向左移12位 */
    private final long workerIdShift = sequenceBits;
    /** 数据标识id向左移17位(12+5) */
    private final long datacenterIdShift = sequenceBits + workerIdBits;
    /** 时间截向左移22位(5+5+12) */
    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    /** 生成序列的掩码,这里为4095 */
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
    /** 工作机器id(0~31) */
    private long workerId = 0L;
    /** 数据中心id(0~31) */
    private long datacenterId = 0L;
    /** 毫秒内序列(0~4095) */
    private long sequence = 0L;
    /** 上次生成ID的时间截 */
    private long lastTimestamp = -1L;

    /**
     * 构造函数
     *
     * @param workerId     工作ID (0~31)
     * @param datacenterId 数据中心ID (0~31)
     */
    public UUIDGenerator(long workerId, long datacenterId) {
    
    
        if (workerId > maxWorkerId || workerId < 0) {
    
    
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
    
    
            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    /**
     * 获得下一个ID (该方法是线程安全的)
     *
     * @return SnowflakeId
     */
    public synchronized long nextId() {
    
    
        long timestamp = timeGen();
        // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过,此时应当抛出异常
        if (timestamp < lastTimestamp) {
    
    
            throw new RuntimeException(
                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        }

        // 如果是同一时间生成的,则进行毫秒内序列
        if (lastTimestamp == timestamp) {
    
    
            sequence = (sequence + 1) & sequenceMask;
            // 毫秒内序列溢出
            if (sequence == 0) {
    
    
                // 阻塞到下一个毫秒,获得新的时间戳
                timestamp = tilNextMillis(lastTimestamp);
            }
        }
        // 时间戳改变,毫秒内序列重置
        else {
    
    
            sequence = 0L;
        }

        // 上次生成ID的时间截
        lastTimestamp = timestamp;

        // 移位并通过或运算拼到一起组成64位的ID
        return ((timestamp - twepoch) << timestampLeftShift) //
                | (datacenterId << datacenterIdShift) //
                | (workerId << workerIdShift) //
                | sequence;
    }

    /**
     * 阻塞到下一个毫秒,直到获得新的时间戳
     *
     * @param lastTimestamp 上次生成ID的时间截
     * @return 当前时间戳
     */
    protected long tilNextMillis(long lastTimestamp) {
    
    
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
    
    
            timestamp = timeGen();
        }
        return timestamp;
    }

    /**
     * 返回以毫秒为单位的当前时间
     *
     * @return 当前时间(毫秒)
     */
    protected long timeGen() {
    
    
        return System.currentTimeMillis();
    }

}
  1. Genere UUID con marca de tiempo y número aleatorio como semilla

import java.util.UUID;

public class UUIDGenerator {
    
    
    public static void main(String[] args) {
    
    
        long time = System.currentTimeMillis();
        int random = (int) (Math.random() * Integer.MAX_VALUE);
        UUID uuid = new UUID(time, random);
        System.out.println("生成的UUID为:" + uuid.toString());
    }
}
  1. Use la clase RUID proporcionada por el marco redisson del clúster de Redis para generar un UUID

import org.redisson.api.RUID;

public class UUIDGenerator {
    
    
    public static void main(String[] args) {
    
    
        RUID ruid = RUID.randomUID();
        System.out.println("生成的UUID为:" + ruid.toString());
    }
}
  1. Generado usando la clase SecureRandom

import java.security.SecureRandom;
import java.util.UUID;

public class UUIDGenerator {
    
    

    public static String generateUUID() {
    
    
        return UUID.randomUUID().toString();
    }

    public static String generateSecureUUID() {
    
    
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[16];
        random.nextBytes(bytes);
        return UUID.nameUUIDFromBytes(bytes).toString();
    }

}

Versión detallada de la biblioteca tripartita

  1. Apache Commons:
    presente las siguientes dependencias de Maven
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

Código de muestra de Java:

import org.apache.commons.lang3.StringUtils;
import java.util.UUID;

public class GenerateUUID {
    
    
    public static void main(String[] args) {
    
    
        UUID uuid = UUID.randomUUID();
        String uuidStr = StringUtils.remove(uuid.toString(), '-');
        System.out.println("UUID:" + uuidStr);
    }
}
  1. Guayaba de Google:

La biblioteca de Google Guava puede usar su clase UUID para generar UUID. Es necesario introducir las siguientes dependencias de Maven:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.0-jre</version>
</dependency>

ejemplo java:

import com.google.common.base.CharMatcher;
import java.util.UUID;

public class GenerateUUID {
    
    
    public static void main(String[] args) {
    
    
        UUID uuid = UUID.randomUUID();
        String uuidStr = CharMatcher.is('-').removeFrom(uuid.toString());
        System.out.println("UUID:" + uuidStr);
    }
}

Precauciones
La clase de herramienta UUIDUtils de Apache Commons se mencionó anteriormente, pero esta clase de herramienta en realidad se usa para convertir formato de cadena y UUID, no para generar UUID.
Si desea usar las clases de utilidad en Apache Commons para generar UUID, puede usar el método randomUUID() en la clase RandomStringUtils. Aquí hay un ejemplo simple:

import org.apache.commons.lang3.RandomStringUtils;

public class GenerateUUID {
    
    
    public static void main(String[] args) {
    
    
        String uuid = RandomStringUtils.randomNumeric(8) + "-" +
                      RandomStringUtils.randomNumeric(4) + "-" +
                      RandomStringUtils.randomNumeric(4) + "-" +
                      RandomStringUtils.randomNumeric(4) + "-" +
                      RandomStringUtils.randomNumeric(12);
        System.out.println("UUID:" + uuid);
    }
}
/*
上述代码中,RandomStringUtils的randomNumeric 
方法用于生成指定长度的数字字符串,然后通过字符串拼接的方式生成UUID。
需要注意的是,这种方式所生成的UUID并不是符合UUID标准规范的。
*/

おすすめ

転載: blog.csdn.net/qq_45699990/article/details/129814826
おすすめ