欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java生成唯一ID的三種方法總結(jié)

 更新時(shí)間:2024年09月21日 10:29:23   作者:長(zhǎng)腿大壯  
單機(jī)環(huán)境下,可以使用AtomicLong來生成唯一ID;而在需要非純數(shù)字形式的場(chǎng)景中,可以通過UUID結(jié)合哈希函數(shù)如MD5或SHA-1轉(zhuǎn)換成數(shù)字,但需注意哈希碰撞的低概率風(fēng)險(xiǎn);對(duì)于分布式系統(tǒng),模擬Snowflake算法是一種復(fù)雜但有效的方法,每種方法都有其適用場(chǎng)景和潛在問題

使用AtomicLong生成唯一ID(適用于單機(jī)場(chǎng)景)

這個(gè)示例已經(jīng)在之前的回答中給出,但我會(huì)再次展示它,以便與后續(xù)示例保持連貫性。

import java.util.concurrent.atomic.AtomicLong;  
  
public class UniqueIdGenerator {  
    private final AtomicLong counter = new AtomicLong(0);  
  
    public long nextId() {  
        return counter.incrementAndGet();  
    }  
  
    public static void main(String[] args) {  
        UniqueIdGenerator generator = new UniqueIdGenerator();  
        long id1 = generator.nextId();  
        long id2 = generator.nextId();  
        System.out.println("ID 1: " + id1);  
        System.out.println("ID 2: " + id2);  
    }  
}

使用UUID并轉(zhuǎn)換為數(shù)字形式(雖然不是純數(shù)字,但提供了唯一性)

由于UUID本身是字符串形式的,我們可以通過哈希函數(shù)(如MD5、SHA-1等)將其轉(zhuǎn)換為數(shù)字,但需要注意哈希碰撞的可能性(盡管在實(shí)際應(yīng)用中非常低)。然而,更常見的是保留UUID的字符串形式或使用其作為基礎(chǔ)來生成符合特定需求的數(shù)字ID。

import java.util.UUID;  
  
public class UuidToNumberExample {  
    // 注意:這不是將UUID直接轉(zhuǎn)換為唯一數(shù)字的有效方法,因?yàn)榇嬖诠E鲎驳娘L(fēng)險(xiǎn)。  
    // 這里只是為了說明概念。  
  
    public static long uuidToNumber(UUID uuid) {  
        // 簡(jiǎn)單的示例:將UUID的字符串表示形式與另一個(gè)數(shù)字組合,然后進(jìn)行哈希(注意:這不是安全的做法)  
        String uuidStr = uuid.toString();  
        long base = 123456789L; // 假設(shè)的基數(shù)  
        // 這里不實(shí)現(xiàn)哈希函數(shù),而是使用字符串長(zhǎng)度加基數(shù)作為示例(僅為演示)  
        return uuidStr.length() + base; // 這不是一個(gè)好的實(shí)現(xiàn)!  
  
        // 更實(shí)際的方法是使用安全的哈希函數(shù),但請(qǐng)注意哈希碰撞的可能性  
        // 并且,由于哈希函數(shù)的輸出是固定長(zhǎng)度的,直接用作ID可能需要進(jìn)一步處理  
    }  
  
    public static void main(String[] args) {  
        UUID uuid = UUID.randomUUID();  
        long number = uuidToNumber(uuid); // 這里的實(shí)現(xiàn)是錯(cuò)誤的,僅用于說明  
        System.out.println("UUID: " + uuid);  
        System.out.println("Converted Number (Incorrect Method): " + number);  
  
        // 正確的做法可能是將UUID用作查找或生成更復(fù)雜ID的基礎(chǔ)  
    }  
}

模擬Snowflake算法生成唯一ID(分布式場(chǎng)景)

Snowflake算法的實(shí)現(xiàn)相對(duì)復(fù)雜,但我們可以簡(jiǎn)化其核心思想來展示一個(gè)基本框架。

public class SnowflakeIdWorker {  
    // 假設(shè)的時(shí)間戳、數(shù)據(jù)中心ID、機(jī)器ID和序列號(hào)字段(實(shí)際應(yīng)用中需要更精細(xì)的管理)  
    private final long twepoch = 1288834974657L; // 自定義起始時(shí)間戳  
    private final long datacenterIdBits = 5L; // 數(shù)據(jù)中心ID位數(shù)  
    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 數(shù)據(jù)中心ID最大值  
    private final long workerIdBits = 5L; // 機(jī)器ID位數(shù)  
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits); // 機(jī)器ID最大值  
    private final long sequenceBits = 12L; // 序列號(hào)位數(shù)  
  
    private final long workerIdShift = sequenceBits; // 機(jī)器ID左移位數(shù)  
    private final long datacenterIdShift = sequenceBits + workerIdBits; // 數(shù)據(jù)中心ID左移位數(shù)  
    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; // 時(shí)間戳左移位數(shù)  
  
    private long sequence = 0L; // 序列號(hào)  
    private long lastTimestamp = -1L; // 上次生成ID的時(shí)間戳  
  
    // 構(gòu)造函數(shù)中初始化workerId和datacenterId(這里為示例,實(shí)際中應(yīng)由外部指定)  
    public SnowflakeIdWorker(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));  
        }  
        // 這里省略了實(shí)際將workerId和datacenterId設(shè)置到對(duì)象中的步驟  
    }  
  
    // 生成ID的方法(簡(jiǎn)化版,未包含時(shí)鐘回?fù)芴幚淼龋? 
    public synchronized long nextId() {  
        long timestamp = timeGen();  
  
        // 如果當(dāng)前時(shí)間小于上一次ID生成的時(shí)間戳,說明系統(tǒng)時(shí)鐘回?fù)苓^  
        if (timestamp < lastTimestamp) {  
            throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));  
        }  
  
        // 如果是同一時(shí)間生成的,則進(jìn)行毫秒內(nèi)序列  
        if (lastTimestamp == timestamp) {  
            sequence = (sequence + 1) & (-1L ^ (-1L << sequenceBits));  
            if (sequence == 0) {  
                // 毫秒內(nèi)序列溢出  
                timestamp = tilNextMillis(lastTimestamp);  
            }  
        } else {  
            // 時(shí)間戳改變,毫秒內(nèi)序列重置  
            sequence = 0L;  
        }  
  
        // 上次生成ID的時(shí)間戳  
        lastTimestamp = timestamp;  
  
        // 移位并通過或運(yùn)算拼到一起組成64位的ID  
        // 這里省略了實(shí)際的workerId和datacenterId的左移和或操作  
        // 示例:return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;  
        return 0L; // 返回模擬的0,實(shí)際應(yīng)返回通過上述方式計(jì)算的ID  
    }  
  
    // 模擬獲取系統(tǒng)當(dāng)前時(shí)間戳(毫秒)  
    protected long timeGen() {  
        return System.currentTimeMillis();  
    }  
  
    // 等待到下一個(gè)毫秒,獲得新的時(shí)間戳  
    protected long tilNextMillis(long lastTimestamp) {  
        long timestamp = timeGen();  
        while (timestamp <= lastTimestamp) {  
            timestamp = timeGen();  
        }  
        return timestamp;  
    }  
  
    // 省略main方法和其他可能的輔助方法...  
}

請(qǐng)注意,上述Snowflake算法的實(shí)現(xiàn)是高度簡(jiǎn)化的,并省略了許多關(guān)鍵細(xì)節(jié)(如實(shí)際的數(shù)據(jù)中心ID和機(jī)器ID的設(shè)置、序列號(hào)的正確處理以及時(shí)鐘回?fù)艿脑敿?xì)處理邏輯)。在實(shí)際應(yīng)用中,您需要根據(jù)自己的需求和環(huán)境來完整實(shí)現(xiàn)這些功能。

總結(jié)

在單機(jī)環(huán)境下,可以使用AtomicLong來生成唯一ID;而在需要非純數(shù)字形式的場(chǎng)景中,可以通過UUID結(jié)合哈希函數(shù)如MD5或SHA-1轉(zhuǎn)換成數(shù)字,但需注意哈希碰撞的低概率風(fēng)險(xiǎn);對(duì)于分布式系統(tǒng),模擬Snowflake算法是一種復(fù)雜但有效的方法,每種方法都有其適用場(chǎng)景和潛在問題,需要根據(jù)具體需求和環(huán)境選擇合適的實(shí)現(xiàn)方式。

到此這篇關(guān)于Java生成唯一ID的三種方法總結(jié)的文章就介紹到這了,更多相關(guān)Java生成唯一ID內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)多選批量刪除功能

    java實(shí)現(xiàn)多選批量刪除功能

    工作中批量刪除可以提高我們的工作效率,今天這篇文章主要介紹了java實(shí)現(xiàn)多選批量刪除功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Mybatis不支持batchInsertOrUpdate返顯id問題

    Mybatis不支持batchInsertOrUpdate返顯id問題

    這篇文章主要介紹了Mybatis不支持batchInsertOrUpdate返顯id問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題

    使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題

    這篇文章主要介紹了使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java?Stream.reduce()用法詳細(xì)解析

    Java?Stream.reduce()用法詳細(xì)解析

    Stream API提供了豐富的中間函數(shù),歸并函數(shù)和終端函數(shù),這些函數(shù)還支持并行化執(zhí)行,下面這篇文章主要給大家介紹了關(guān)于Java?Stream.reduce()用法的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • springmvc接口接收參數(shù)與請(qǐng)求參數(shù)格式的整理

    springmvc接口接收參數(shù)與請(qǐng)求參數(shù)格式的整理

    這篇文章主要介紹了springmvc接口接收參數(shù)與請(qǐng)求參數(shù)格式的整理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • JAVA如何讀取Excel數(shù)據(jù)

    JAVA如何讀取Excel數(shù)據(jù)

    這篇文章主要介紹了JAVA如何讀取Excel數(shù)據(jù),幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-09-09
  • Java實(shí)現(xiàn)調(diào)用jython執(zhí)行python文件的方法

    Java實(shí)現(xiàn)調(diào)用jython執(zhí)行python文件的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)調(diào)用jython執(zhí)行python文件的方法,結(jié)合實(shí)例形式分析了Java調(diào)用jython執(zhí)行python文件的常見操作技巧及相關(guān)問題解決方法,需要的朋友可以參考下
    2018-03-03
  • Java經(jīng)典排序算法之插入排序代碼實(shí)例

    Java經(jīng)典排序算法之插入排序代碼實(shí)例

    這篇文章主要介紹了Java經(jīng)典排序算法之插入排序代碼實(shí)例,插入排序是一種最簡(jiǎn)單直觀的排序算法,它的工作原理是通過構(gòu)建有序序列,對(duì)于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入,需要的朋友可以參考下
    2023-10-10
  • 深入了解Java中的static關(guān)鍵字

    深入了解Java中的static關(guān)鍵字

    這篇文章主要為大家詳細(xì)介紹了Java中的static關(guān)鍵字的用法的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-11-11
  • springboot中如何替換class文件

    springboot中如何替換class文件

    這篇文章主要介紹了springboot中如何替換class文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論