色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

數據集中如何判斷元素是否存在

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

Guava BloomFilter

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

基本概念

當需要判斷某個元素是否在某個數據集中時,一般會怎么做?

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

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

也就是 布隆過濾器

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

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

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

應用場景

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

優缺點

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

實現原理

圖片

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

  • put 將元素放入過濾器中,但不是存儲
public < T > boolean put(@ParametricNullness T object, Funnel< ? super T > funnel, int numHashFunctions, LockFreeBitArray bits) {
            long bitSize = bits.bitSize(); // 位數組,可以通過redis來實現分布式的布隆過濾器
            long hash64 = Hashing.murmur3_128().hashObject(object, funnel).asLong(); //通過funnel將對象轉換成基本類型并計算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相似,計算的過程相同,不同的是值的判斷
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;
        }

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

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

為什么判斷元素一定不在集合中呢?很顯然,如果一個元素存在,則該元素hash后的bit數組必須全部都是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- >{
            // 正常情況下全部失敗,但是會有 20%的返回true
            System.out.println( id + ":" + filter.mightContain( id+1 ));
        });
    }

流程很簡單:

  1. 根據配置構建BloomFilter對象
  2. 通過put方法,初始化數據到filter
  3. 通過方法mightContain判斷元素是否存在

結束語

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • API
    API
    +關注

    關注

    2

    文章

    1499

    瀏覽量

    61962
  • 緩存
    +關注

    關注

    1

    文章

    239

    瀏覽量

    26669
  • 函數
    +關注

    關注

    3

    文章

    4327

    瀏覽量

    62569
  • 過濾器
    +關注

    關注

    1

    文章

    428

    瀏覽量

    19593
  • 數據集
    +關注

    關注

    4

    文章

    1208

    瀏覽量

    24689
收藏 人收藏

    評論

    相關推薦

    如何準確判斷集中電路IC是否正常工作?

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

    如何判斷鏈表是否有環

    如何判斷鏈表是否有環?
    發表于 08-10 17:07 ?663次閱讀
    如何<b class='flag-5'>判斷</b>鏈表<b class='flag-5'>是否</b>有環

    LabVIEW如何識別接線端是否數據輸入,不能通過判斷默認值的方式

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

    C語言中怎么判斷數組元素的個數

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

    float類型數據是否合理判斷

    float類型數據是否合理判斷_chkfloat_單片機內嵌函數是怎么實現的?也就是怎么判斷一個float數據
    發表于 07-22 16:17

    快速判斷一維數組元素是否有重復

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

    請問如何判斷一個任務是否存在或者已經刪除?

    ) == osThreadDeleted來判斷是否被刪除,可是在第一次運行時,也就是XXXTask并不存在時,程序會卡死在configASSERT( pxTCB );因為pxTCB = ( TCB_t * ) xTask
    發表于 06-09 09:11

    如何判斷輸出圖像數據是否正常?

    如何判斷輸出圖像數據是否正常?
    發表于 02-15 06:59

    Arm AMBA協議集中是否存在無效數據填充導致效率降低的問題

    Arm AMBA協議集中,當總線位寬很寬時(如2048bit),是否存在無效數據填充導致效率降低的問題?AXI協議是否支持segment(
    發表于 09-14 11:42

    怎樣判斷放大器是否存在自激振蕩?如何進行消除呢?

    怎樣判斷放大器是否存在自激振蕩?如何進行消除呢?
    發表于 04-26 14:43

    C語言教程之判斷一個數是否存在數組中

    C語言教程之判斷一個數是否存在數組中,很好的C語言資料,快來學習吧。
    發表于 04-25 15:13 ?0次下載

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

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

    如何判斷網絡是否存在二層環路

    方法只能看到網絡的當前流量結果,此時需要和網絡的正常業務量進行比較,流量遠大于正常業務流量時,才能判斷可能存在二層環路。如果流量只是稍大時,或者設備部署了廣播抑制,就不能判斷出環路了,需要使用其他方法
    發表于 12-16 15:44 ?3283次閱讀

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

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

    js判斷是否在數組中存在

    JavaScript 是一種用于客戶端和服務器端編程的腳本語言。它提供了許多內置函數和方法,以便進行數組操作。 在本文中,我們將學習如何使用 JavaScript 來判斷一個元素是否存在
    的頭像 發表于 11-30 16:23 ?1133次閱讀
    主站蜘蛛池模板: 欧美中文字幕一区二区三区| 草莓视频免费看| 久久这里只有精品视频e| 亚洲视频在线观看视频| 精品国产手机视频在在线| 亚洲熟妇无码乱子AV电影| 久久精品99热超碰| 中国农民真实bbwbbw| 久热这里只有精品99国产6| 2018久久视频在线视频观看| 蜜桃AV色欲A片精品一区| 99精品在线播放| 青柠在线观看视频在线| 超碰视频在线| 无人区在线日本高清免费| 国产露脸150部国语对白| 亚洲精品色播一区二区 | 91精品在线国产| 年轻的母亲4线在线观看完整| 99手机在线视频| 日韩a视频在线观看| 国产成人女人在线视频观看| 亚州三级久久电影| 精品午夜中文字幕熟女人妻在线| 伊人无码高清| 母乳女神春日もな| 菠萝蜜国际一区麻豆| 无码成人AAAAA毛片含羞草| 国产国拍亚洲精品av麻豆| 亚洲精品福利在线| 久久re这里精品在线视频7| 7756短视频| 日韩视频中文字幕精品偷拍| 国产三级视频在线| 伊人精品国产| 暖暖视频免费观看社区| 大伊人青草狠狠久久| 亚洲地址一地址二地址三| 久亚洲AV无码专区A片| 白丝制服被啪到喷水很黄很暴力| 天堂so导航|