在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

數(shù)據(jù)集中如何判斷元素是否存在

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-07 16:43 ? 次閱讀

Guava BloomFilter

布隆過濾器是一個(gè)很長的二進(jìn)制向量和一系列隨機(jī)映射函數(shù)。布隆過濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢時(shí)間都比一般的算法要好的多,缺點(diǎn)是有一定的誤識(shí)別率和刪除困難。

基本概念

當(dāng)需要判斷某個(gè)元素是否在某個(gè)數(shù)據(jù)集中時(shí),一般會(huì)怎么做?

  1. 將數(shù)據(jù)集封裝成集合,比如List、Set等
  2. 通過集合提供的API判斷該元素是否存在于集合

這樣的實(shí)現(xiàn)比較簡單,同時(shí)通過現(xiàn)有的JDK都能很快達(dá)到目的,但是設(shè)想一下,如果上面說到的集合數(shù)據(jù)量非常的大,這樣不僅會(huì)耗費(fèi)較大的存儲(chǔ)空間,同時(shí) 在集合中檢索元素的時(shí)間復(fù)雜度也會(huì)隨之增加。那么有沒比較好的方法去實(shí)現(xiàn)判斷元素是否存在這樣的情形呢?

也就是 布隆過濾器

通過一系列的Hash函數(shù)將元素映射到一個(gè)位陣列(Bit Array)中的多個(gè)點(diǎn)位上,判斷元素是否存在,則是判斷所有點(diǎn)位是不是都為1。然而,位陣列上都為1并不一定能夠保證該元素一定存在,也有可能是其他元素Hash后落在了該點(diǎn)位上,這就是布隆過濾器的誤判。

因此通過布隆過濾器我們可以確定:

  1. 元素可能在集合中
  2. 元素一定不在集合中

應(yīng)用場(chǎng)景

  • 網(wǎng)頁爬蟲時(shí)忽略已經(jīng)判定的URL路徑
  • 郵箱通過設(shè)置過濾垃圾郵件
  • 集合重復(fù)元素的判別,有效判斷元素不在集合中
  • 防止數(shù)據(jù)緩存時(shí)的緩存穿透問題

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn)
    • 相比于其它的數(shù)據(jù)結(jié)構(gòu),布隆過濾器在空間和時(shí)間方面都有巨大的優(yōu)勢(shì)。
    • 布隆過濾器存儲(chǔ)空間和插入/查詢時(shí)間都是常數(shù)。
    • Hash函數(shù)相互之間沒有關(guān)系,方便由硬件并行實(shí)現(xiàn)。
    • 布隆過濾器不需要存儲(chǔ)元素本身,對(duì)保密要求非常嚴(yán)格的場(chǎng)合有優(yōu)勢(shì)。
    • 布隆過濾器可以表示全集,其它任何數(shù)據(jù)結(jié)構(gòu)都不能。
  • 缺點(diǎn)
    • 元素存在的誤判
    • 一般情況下不支持元素(位陣列)的刪除

實(shí)現(xiàn)原理

圖片

核心其實(shí)是元素如何存儲(chǔ)?如何判斷元素是否存在?核心方法就兩個(gè),一個(gè)“存”一個(gè)檢查,里面涉及到了算法相關(guān)知識(shí),感興趣可以深入研究下其實(shí)現(xiàn)原理與思想。

  • put 將元素放入過濾器中,但不是存儲(chǔ)
public < T > boolean put(@ParametricNullness T object, Funnel< ? super T > funnel, int numHashFunctions, LockFreeBitArray bits) {
            long bitSize = bits.bitSize(); // 位數(shù)組,可以通過redis來實(shí)現(xiàn)分布式的布隆過濾器
            long hash64 = Hashing.murmur3_128().hashObject(object, funnel).asLong(); //通過funnel將對(duì)象轉(zhuǎn)換成基本類型并計(jì)算64位hash
            int hash1 = (int)hash64; // 取低32位
            int hash2 = (int)(hash64 > >> 32); // 取高32位
            boolean bitsChanged = false;
            // 
            for(int i = 1; i <= numHashFunctions; ++i) {
                int combinedHash = hash1 + i * hash2;
                if (combinedHash < 0) {
                    combinedHash = ~combinedHash;
                }

                bitsChanged |= bits.set((long)combinedHash % bitSize);
            }

            return bitsChanged;
        }
  • mightContain 與put相似,計(jì)算的過程相同,不同的是值的判斷
public < T > boolean mightContain(@ParametricNullness T object, Funnel< ? super T > funnel, int numHashFunctions, LockFreeBitArray bits) {
            long bitSize = bits.bitSize();
            long hash64 = Hashing.murmur3_128().hashObject(object, funnel).asLong();
            int hash1 = (int)hash64;
            int hash2 = (int)(hash64 > >> 32);

            for(int i = 1; i <= numHashFunctions; ++i) {
                int combinedHash = hash1 + i * hash2;
                if (combinedHash < 0) {
                    combinedHash = ~combinedHash;
                }

                if (!bits.get((long)combinedHash % bitSize)) {
                    return false;
                }
            }

            return true;
        }

我們可以簡單第理解其實(shí)現(xiàn)原理?比如現(xiàn)在有一個(gè)容器,我們定義為String[] bitArray = new String[26]作為 位陣列 , 現(xiàn)在有一堆由小寫英文組成的元素,我們假定Hash算法為a-z到1~26的映射。

  1. 現(xiàn)在有一個(gè)元素abc,hash后為1110000000...,保存到bitArray :1110000000...
  2. 現(xiàn)在有一個(gè)元素cde, hash后為0011100000...,保存到bitArray :1111100000...
  3. 現(xiàn)在又有一個(gè)新的元素ade,hash后同樣為100110000...,很明顯會(huì)認(rèn)為該元素存在,這就是FFP

為什么判斷元素一定不在集合中呢?很顯然,如果一個(gè)元素存在,則該元素hash后的bit數(shù)組必須全部都是1,反之則不存在

示例

@Test
    public void match(){
        BloomFilter filter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()),10000,0.2);
        List< String > ids = new ArrayList<  >();

        IntStream.rangeClosed(1,10000).forEach(index- >{
            String id = UUID.randomUUID().toString();
            ids.add(id);
            filter.put( id );
        });

        ids.forEach(id- >{
            // 正常情況下全部失敗,但是會(huì)有 20%的返回true
            System.out.println( id + ":" + filter.mightContain( id+1 ));
        });
    }

流程很簡單:

  1. 根據(jù)配置構(gòu)建BloomFilter對(duì)象
  2. 通過put方法,初始化數(shù)據(jù)到filter
  3. 通過方法mightContain判斷元素是否存在

結(jié)束語

BloomFilter雖然看起來簡單,但是其內(nèi)部的實(shí)現(xiàn)包含了很多的數(shù)學(xué)與算法知識(shí),我們只是通過其簡單的API就能各種復(fù)雜的功能。關(guān)于如何將目前說到的這些在具體的項(xiàng)目中進(jìn)行實(shí)踐與集成 后面會(huì)來介紹,首先我們能夠先了解一些技術(shù)一起能解決上面問題,理解了原理與目的,使用也就不是難事。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1501

    瀏覽量

    62027
  • 緩存
    +關(guān)注

    關(guān)注

    1

    文章

    240

    瀏覽量

    26679
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4331

    瀏覽量

    62622
  • 過濾器
    +關(guān)注

    關(guān)注

    1

    文章

    429

    瀏覽量

    19614
  • 數(shù)據(jù)集
    +關(guān)注

    關(guān)注

    4

    文章

    1208

    瀏覽量

    24703
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何準(zhǔn)確判斷集中電路IC是否正常工作?

    如何準(zhǔn)確判斷電路中集成電路IC是否“偷懶”沒處在工作狀態(tài),是好是壞是修理電視、音響、錄像設(shè)備的一個(gè)重要內(nèi)容,判斷不準(zhǔn),往往花大力氣換上新集成電路而故障依然存在,所以要對(duì)集成電路作出正確
    的頭像 發(fā)表于 12-29 09:27 ?2w次閱讀

    如何判斷鏈表是否有環(huán)

    如何判斷鏈表是否有環(huán)?
    發(fā)表于 08-10 17:07 ?669次閱讀
    如何<b class='flag-5'>判斷</b>鏈表<b class='flag-5'>是否</b>有環(huán)

    LabVIEW如何識(shí)別接線端是否數(shù)據(jù)輸入,不能通過判斷默認(rèn)值的方式

    ”接線端的默認(rèn)值為0。該接線端不連接時(shí),實(shí)際操作為刪去最后一個(gè)元素;寫默認(rèn)值0時(shí)實(shí)際操作為刪去索引0的元素。由此可見,這個(gè)函數(shù)可以識(shí)別接線端是否數(shù)據(jù)輸入,并且不是通過
    發(fā)表于 09-24 10:53

    C語言中怎么判斷數(shù)組元素的個(gè)數(shù)

    C語言中怎么判斷數(shù)組元素的個(gè)數(shù),如數(shù)組:int array[]={45,56,76,234,1,34,23,2,3};
    發(fā)表于 05-26 11:49

    float類型數(shù)據(jù)是否合理判斷

    float類型數(shù)據(jù)是否合理判斷_chkfloat_單片機(jī)內(nèi)嵌函數(shù)是怎么實(shí)現(xiàn)的?也就是怎么判斷一個(gè)float數(shù)據(jù)
    發(fā)表于 07-22 16:17

    快速判斷一維數(shù)組元素是否有重復(fù)

    今天在編寫一個(gè)程序時(shí)要判斷一維數(shù)組元素是否有重復(fù),想了想做了個(gè)簡單判斷的程序,和大家分享一下思路,歡迎各位高手前輩提供更佳的思路方案。
    發(fā)表于 01-10 09:59

    請(qǐng)問如何判斷一個(gè)任務(wù)是否存在或者已經(jīng)刪除?

    ) == osThreadDeleted來判斷是否被刪除,可是在第一次運(yùn)行時(shí),也就是XXXTask并不存在時(shí),程序會(huì)卡死在configASSERT( pxTCB );因?yàn)閜xTCB = ( TCB_t * ) xTask
    發(fā)表于 06-09 09:11

    如何判斷輸出圖像數(shù)據(jù)是否正常?

    如何判斷輸出圖像數(shù)據(jù)是否正常?
    發(fā)表于 02-15 06:59

    Arm AMBA協(xié)議集中是否會(huì)存在無效數(shù)據(jù)填充導(dǎo)致效率降低的問題

    Arm AMBA協(xié)議集中,當(dāng)總線位寬很寬時(shí)(如2048bit),是否會(huì)存在無效數(shù)據(jù)填充導(dǎo)致效率降低的問題?AXI協(xié)議是否支持segment(
    發(fā)表于 09-14 11:42

    C語言教程之判斷一個(gè)數(shù)是否存在數(shù)組中

    C語言教程之判斷一個(gè)數(shù)是否存在數(shù)組中,很好的C語言資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-25 15:13 ?0次下載

    Linux中如何判斷文件夾是否存在并新建文件夾

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux中如何判斷文件夾是否存在并新建文件夾vi文件免費(fèi)下載。
    發(fā)表于 01-17 08:00 ?8次下載
    Linux中如何<b class='flag-5'>判斷</b>文件夾<b class='flag-5'>是否</b><b class='flag-5'>存在</b>并新建文件夾

    如何判斷網(wǎng)絡(luò)是否存在二層環(huán)路

    方法只能看到網(wǎng)絡(luò)的當(dāng)前流量結(jié)果,此時(shí)需要和網(wǎng)絡(luò)的正常業(yè)務(wù)量進(jìn)行比較,流量遠(yuǎn)大于正常業(yè)務(wù)流量時(shí),才能判斷可能存在二層環(huán)路。如果流量只是稍大時(shí),或者設(shè)備部署了廣播抑制,就不能判斷出環(huán)路了,需要使用其他方法
    發(fā)表于 12-16 15:44 ?3293次閱讀

    怎樣判斷放大器是否存在自激振蕩?如何進(jìn)行消除?

    怎樣判斷放大器是否存在自激振蕩?如何進(jìn)行消除?? 放大器是電子器件中應(yīng)用最廣泛的一種電路,其作用是在保持電信號(hào)形狀不失真的前提下將信號(hào)幅度放大,從而擴(kuò)大信號(hào)的傳輸范圍和距離。然而,由于各種因素
    的頭像 發(fā)表于 09-18 09:16 ?6154次閱讀

    js判斷是否在數(shù)組中存在

    JavaScript 是一種用于客戶端和服務(wù)器端編程的腳本語言。它提供了許多內(nèi)置函數(shù)和方法,以便進(jìn)行數(shù)組操作。 在本文中,我們將學(xué)習(xí)如何使用 JavaScript 來判斷一個(gè)元素是否存在
    的頭像 發(fā)表于 11-30 16:23 ?1145次閱讀

    如何判斷電感是否損壞嗎

    電子發(fā)燒友網(wǎng)站提供《如何判斷電感是否損壞嗎.docx》資料免費(fèi)下載
    發(fā)表于 01-22 09:25 ?0次下載
    主站蜘蛛池模板: 奇米影视亚洲狠狠色777不卡| 亚洲一区二区影视| 色婷婷激情五月| 四虎传媒| 丁香伊人五月综合激激激| 四虎影永久地址www| 好男人午夜www视频在线观看| 天天操天天操天天干| 一区卡二区卡三区卡视频| 四虎影视在线播放| www.瑟瑟| h网站在线观看| 日本特黄a级高清免费酷网| 亚洲精品系列| 亚洲性一区| 欧美日韩在线成人免费| 日韩特黄| h网站亚洲| 红色一级毛片| 成人黄色三级| 视频色版| 亚洲第一视频在线| 久久99热精品| 韩国三级理在线视频观看| 1024你懂的国产欧美日韩在| 五月激情综合| 一级特黄aaa免费| 特黄aa级毛片免费视频播放| 性色影院| 免费观看黄色在线视频| 奇米9999| 五月天精品| 亚洲黄色录像| 国产性做久久久久久| 国产精品久久婷婷六月丁香| 欧美jizz大又粗| 亚洲国产成人在线| 亚洲综合色网站| yy肉戏多纯黄的小说| 国产成人精品亚洲日本在线| 中文字幕视频二区|