当前位置: 首页 > 图灵资讯 > 技术篇> java es 生成id

java es 生成id

来源:图灵教育
时间:2023-07-20 17:20:48

用Java生成唯一的ID方法

在开发过程中,生成唯一的ID是一个非常常见的需求。在Java中,生成唯一ID的方法有很多。本文将介绍一些常见的方法,并提供相应的代码示例。

1. 使用UUID类

UUID(Universally Unique Identifier)它是唯一识别信息的标准化128位值。Java提供UUID类,可以轻松生成UUID。

import java.util.UUID;public class UuidDemo {    public static void main(String[] args) {        UUID uuid = UUID.randomUUID();        String id = uuid.toString();        System.out.println("生成的UUID:" + id);    }}

使用上述代码UUID.randomUUID()该方法生成UUID,并将其转换为字符串形式。操作程序,输出类似于1b29ff5d-98cd-4a3e-8c47-04982043唯一的ID。

UUID的优点是简单快捷,生成的ID长度固定。但由于它是基于随机数生成的,不适合作为数据库的主键或排序依据。

2. 使用Snowflake算法

Snowflake算法是Twitter开源生成唯一ID的算法。其核心思想是将64位longID分为多个部分,分别表示时间戳和机器ID、数据中心ID和序列号。在实际应用中,我们可以根据需要调整各部分的位数。

以下是示例代码:

public class SnowflakeDemo {    private final long startTime = 1624454400000L;  // 起始时间戳(2021-06-24)    private final long dataCenterIdBits = 5L;       // ID位数的数据中心    private final long workerIdBits = 5L;           // 机器ID位数    private final long sequenceBits = 12L;          // 序列号位数    private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);    private final long workerIdShift = sequenceBits;    private final long dataCenterIdShift = sequenceBits + workerIdBits;    private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;    private long workerId;    private long dataCenterId;    private long sequence = 0L;    private long lastTimestamp = -1L;    public SnowflakeDemo(long dataCenterId, long workerId) {        if (dataCenterId > maxDataCenterId || dataCenterId < 0) {            throw new IllegalArgumentException("Data center ID can't be greater than " + maxDataCenterId + " or less than 0");        }        if (workerId > maxWorkerId || workerId < 0) {            throw new IllegalArgumentException("Worker ID can't be greater than " + maxWorkerId + " or less than 0");        }        this.dataCenterId = dataCenterId;        this.workerId = workerId;    }    public synchronized long nextId() {        long timestamp = System.currentTimeMillis();        if (timestamp < lastTimestamp) {            throw new RuntimeException("Clock moved backwards. Refusing to generate ID");        }        if (timestamp == lastTimestamp) {            sequence = (sequence + 1) & ((1 << sequenceBits) - 1);            if (sequence == 0) {                timestamp = tilNextMillis(lastTimestamp);            }        } else {            sequence = 0L;        }        lastTimestamp = timestamp;        return ((timestamp - startTime) << timestampLeftShift) |                (dataCenterId << dataCenterIdShift) |                (workerId << workerIdShift) |                sequence;    }    private long tilNextMillis(long lastTimestamp) {        long timestamp = System.currentTimeMillis();        while (timestamp <= lastTimestamp) {            timestamp = System.currentTimeMillis();        }        return timestamp;    }    public static void main(String[] args) {        SnowflakeDemo snowflake = new SnowflakeDemo(1, 1);        long id = snowflake.nextId();        System.out.println("生成的ID:" + id);    }}

Snowflake算法实现了上述代码startTime表示启动时间戳,dataCenterIdBitsworkerIdBitssequenceBits表示每个部分的位数。构造函数中传入的位数dataCenterIdworkerId数据中心ID和机器ID分别表示。nextId()通过左移、或运算和运算生成下一个唯一的ID