日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

布隆過濾器的原理以及java 簡(jiǎn)單實(shí)現(xiàn)

瀏覽:18日期:2022-08-20 14:33:19

一.布隆過濾器

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

如果想判斷一個(gè)元素是不是在一個(gè)集合里,一般想到的是將集合中所有元素保存起來,然后通過比較確定。鏈表、樹、散列表(又叫哈希表,Hash table)等等數(shù)據(jù)結(jié)構(gòu)都是這種思路。但是隨著集合中元素的增加,我們需要的存儲(chǔ)空間越來越大。同時(shí)檢索速度也越來越慢,上述三種結(jié)構(gòu)的檢索時(shí)間復(fù)雜度分別為:O(n), O(log n), O(n/k)。

布隆過濾器的原理是,當(dāng)一個(gè)元素被加入集合時(shí),通過K個(gè)Hash函數(shù)將這個(gè)元素映射成一個(gè)位數(shù)組中的K個(gè)點(diǎn),把它們置為1。檢索時(shí),我們只要看看這些點(diǎn)是不是都是1就(大約)知道集合中有沒有它了:如果這些點(diǎn)有任何一個(gè)0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。這就是布隆過濾器的基本思想。

布隆過濾器數(shù)據(jù)結(jié)構(gòu)

布隆過濾器是一個(gè) bit 向量或者說 bit 數(shù)組,長(zhǎng)這樣:

布隆過濾器的原理以及java 簡(jiǎn)單實(shí)現(xiàn)

如果我們要映射一個(gè)值到布隆過濾器中,我們需要使用多個(gè)不同的哈希函數(shù)生成多個(gè)哈希值,并對(duì)每個(gè)生成的哈希值指向的 bit 位置 1,例如針對(duì)值 “baidu” 和三個(gè)不同的哈希函數(shù)分別生成了哈希值 1、4、7,則上圖轉(zhuǎn)變?yōu)椋?/p>

布隆過濾器的原理以及java 簡(jiǎn)單實(shí)現(xiàn)

值得注意的是,4 這個(gè) bit 位由于兩個(gè)值的哈希函數(shù)都返回了這個(gè) bit 位,因此它被覆蓋了。現(xiàn)在我們?nèi)绻氩樵?“dianping” 這個(gè)值是否存在,哈希函數(shù)返回了 1、5、8三個(gè)值,結(jié)果我們發(fā)現(xiàn) 5 這個(gè) bit 位上的值為 0,說明沒有任何一個(gè)值映射到這個(gè) bit 位上,因此我們可以很確定地說 “dianping” 這個(gè)值不存在。而當(dāng)我們需要查詢 “baidu” 這個(gè)值是否存在的話,那么哈希函數(shù)必然會(huì)返回 1、4、7,然后我們檢查發(fā)現(xiàn)這三個(gè) bit 位上的值均為 1,那么我們可以說 “baidu” 存在了么?答案是不可以,只能是 “baidu” 這個(gè)值可能存在。

這是為什么呢?答案跟簡(jiǎn)單,因?yàn)殡S著增加的值越來越多,被置為 1 的 bit 位也會(huì)越來越多,這樣某個(gè)值 “taobao” 即使沒有被存儲(chǔ)過,但是萬一哈希函數(shù)返回的三個(gè) bit 位都被其他值置位了 1 ,那么程序還是會(huì)判斷 “taobao” 這個(gè)值存在。

支持刪除么

目前我們知道布隆過濾器可以支持 add 和 isExist 操作,那么 delete 操作可以么,答案是不可以,例如上圖中的 bit 位 4 被兩個(gè)值共同覆蓋的話,一旦你刪除其中一個(gè)值例如 “tencent” 而將其置位 0,那么下次判斷另一個(gè)值例如 “baidu” 是否存在的話,會(huì)直接返回 false,而實(shí)際上你并沒有刪除它。

如何解決這個(gè)問題,答案是計(jì)數(shù)刪除。但是計(jì)數(shù)刪除需要存儲(chǔ)一個(gè)數(shù)值,而不是原先的 bit 位,會(huì)增大占用的內(nèi)存大小。這樣的話,增加一個(gè)值就是將對(duì)應(yīng)索引槽上存儲(chǔ)的值加一,刪除則是減一,判斷是否存在則是看值是否大于0。

代碼簡(jiǎn)單實(shí)現(xiàn)布隆過濾器

package com.jd.demo.test;import java.util.Arrays;import java.util.BitSet;import java.util.concurrent.atomic.AtomicBoolean;public class MyBloomFilter { //你的布隆過濾器容量 private static final int DEFAULT_SIZE = 2 << 28; //bit數(shù)組,用來存放結(jié)果 private static BitSet bitSet = new BitSet(DEFAULT_SIZE); //后面hash函數(shù)會(huì)用到,用來生成不同的hash值,可隨意設(shè)置,別問我為什么這么多8,圖個(gè)吉利 private static final int[] ints = {1, 6, 16, 38, 58, 68}; //add方法,計(jì)算出key的hash值,并將對(duì)應(yīng)下標(biāo)置為true public void add(Object key) { Arrays.stream(ints).forEach(i -> bitSet.set(hash(key, i))); } //判斷key是否存在,true不一定說明key存在,但是false一定說明不存在 public boolean isContain(Object key) { boolean result = true; for (int i : ints) { //短路與,只要有一個(gè)bit位為false,則返回false result = result && bitSet.get(hash(key, i)); } return result; } //hash函數(shù),借鑒了hashmap的擾動(dòng)算法 private int hash(Object key, int i) { int h; return key == null ? 0 : (i * (DEFAULT_SIZE - 1) & ((h = key.hashCode()) ^ (h >>> 16))); }}

測(cè)試

public static void main(String[] args) { MyNewBloomFilter myNewBloomFilter = new MyNewBloomFilter(); myNewBloomFilter.add('張學(xué)友'); myNewBloomFilter.add('郭德綱'); myNewBloomFilter.add(666); System.out.println(myNewBloomFilter.isContain('張學(xué)友'));//true System.out.println(myNewBloomFilter.isContain('張學(xué)友 '));//false System.out.println(myNewBloomFilter.isContain('張學(xué)友1'));//false System.out.println(myNewBloomFilter.isContain('郭德綱'));//true System.out.println(myNewBloomFilter.isContain(666));//true System.out.println(myNewBloomFilter.isContain(888));//false}

二.具體代碼使用

在實(shí)際應(yīng)用當(dāng)中,我們不需要自己去實(shí)現(xiàn)BloomFilter。可以使用Guava提供的相關(guān)類庫即可。

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

判斷一個(gè)元素是否在集合中

public class Test1 { private static int size = 1000000; private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size); public static void main(String[] args) { for (int i = 0; i < size; i++) { bloomFilter.put(i); } long startTime = System.nanoTime(); // 獲取開始時(shí)間 //判斷這一百萬個(gè)數(shù)中是否包含29999這個(gè)數(shù) if (bloomFilter.mightContain(29999)) { System.out.println('命中了'); } long endTime = System.nanoTime(); // 獲取結(jié)束時(shí)間 System.out.println('程序運(yùn)行時(shí)間: ' + (endTime - startTime) + '納秒'); }}

運(yùn)行結(jié)果如下:

命中了程序運(yùn)行時(shí)間: 441616納秒

自定義錯(cuò)誤率

public class Test3 { private static int size = 1000000; private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.01); public static void main(String[] args) { for (int i = 0; i < size; i++) { bloomFilter.put(i); } List<Integer> list = new ArrayList<Integer>(1000); // 故意取10000個(gè)不在過濾器里的值,看看有多少個(gè)會(huì)被認(rèn)為在過濾器里 for (int i = size + 10000; i < size + 20000; i++) { if (bloomFilter.mightContain(i)) {list.add(i); } } System.out.println('誤判的數(shù)量:' + list.size()); }}

運(yùn)行結(jié)果如下:

誤判的數(shù)量:941

對(duì)于緩存宕機(jī)的場(chǎng)景,使用白名單或者布隆過濾器都有可能會(huì)造成一定程度的誤判。原因是除了Bloom Filter 本身有誤判率,宕機(jī)之前的緩存不一定能覆蓋到所有DB中的數(shù)據(jù),當(dāng)宕機(jī)后用戶請(qǐng)求了一個(gè)以前從未請(qǐng)求的數(shù)據(jù),這個(gè)時(shí)候就會(huì)產(chǎn)生誤判。當(dāng)然,緩存宕機(jī)時(shí)使用白名單/布隆過濾器作為應(yīng)急的方式,這種情況應(yīng)該也是可以忍受的。

以上就是布隆過濾器的原理以及java 簡(jiǎn)單實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于java 布隆過濾器的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩av影院| 久久精品资源| 999久久久精品国产| 国模精品一区| 福利一区在线| 天堂а√在线最新版中文在线| 大香伊人久久精品一区二区| 岛国av在线播放| 久久国产中文字幕| 欧美一区二区三区高清视频| 国产综合精品| 视频在线观看91| 中文字幕一区二区三区在线视频| 日韩欧美四区| 日韩高清不卡在线| 国产精品美女午夜爽爽| 麻豆91精品91久久久的内涵| 欧美激情国产在线| 久久三级福利| 免费观看在线综合| 国产亚洲高清在线观看| 久久av导航| 成人片免费看| 在线视频亚洲| 97久久亚洲| 成人国产综合| 亚洲精品一二三区区别| 综合在线一区| 久久精品99久久久| 高清不卡一区| 欧美日韩国产一区精品一区| 亚洲专区视频| 美日韩一区二区三区| 日韩免费久久| 久久国产精品亚洲77777| 91嫩草精品| 国产一区国产二区国产三区| 2023国产精品久久久精品双| 涩涩涩久久久成人精品| 精品视频久久| 中文国产一区| 国产精品白丝一区二区三区| 精品免费av在线| 亚洲日产av中文字幕| 欧美精品第一区| 欧美+日本+国产+在线a∨观看| 日本久久一区| 香蕉成人av| 日本电影久久久| 精品三级久久| 中文字幕日本一区| 亚洲欧洲美洲av| 亚洲欧美在线综合| av日韩中文| 日本不卡在线视频| 青青久久av| 青草国产精品久久久久久| av在线日韩| 国产欧美一区二区三区米奇| 久久久久欧美精品| 欧美啪啪一区| 国产婷婷精品| 日韩成人精品一区二区| 综合色就爱涩涩涩综合婷婷| 日韩在线免费| 国产欧美一区| 日韩制服丝袜av| 日韩欧美一区二区三区在线观看 | 亚洲欧美日韩国产一区二区| 国产精品成人自拍| 夜夜嗨一区二区| 大香伊人久久精品一区二区| 亚洲丝袜美腿一区| 久久久噜噜噜| 免费视频一区二区三区在线观看| 在线观看免费一区二区| 精品一区视频| 日本aⅴ免费视频一区二区三区| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 国产精品中文| 亚洲精品网址| 午夜久久中文| 久久99久久人婷婷精品综合| 蜜臀精品久久久久久蜜臀| se01亚洲视频| 狠狠久久伊人| 亚洲一二av| 午夜av一区| 亚洲综合电影| 精品色999| 97久久亚洲| 亚洲精品麻豆| 久久成人国产| 影院欧美亚洲| 欧美精品一二| 午夜精品成人av| 91日韩在线| 精品国产一区二区三区噜噜噜| 欧美在线看片| 婷婷亚洲成人| 在线日韩成人| 天堂成人国产精品一区| 欧美日韩国产v| 日韩精品dvd| 六月婷婷综合| 国产不卡一区| 麻豆91精品视频| 国产精品欧美在线观看| 日韩高清一区在线| 亚洲精品免费观看| 爽爽淫人综合网网站| 伊人久久亚洲影院| 午夜久久黄色| 伊人成人网在线看| 亚洲免费播放| 亚洲经典在线| 国产一级久久| 91久久国产| 在线看片不卡| 日韩视频二区| 香蕉久久久久久久av网站| 黄色免费成人| 免费视频久久| 蜜桃视频免费观看一区| 视频一区二区国产| 日韩中文字幕av电影| 日韩中文字幕不卡| 综合在线一区| 青青青国产精品| 日韩国产91| 国产精品对白久久久久粗| 国产精品天堂蜜av在线播放| 91综合久久爱com| 国产精品三级| 国产 日韩 欧美 综合 一区| 国产亚洲一区二区手机在线观看| 久久久国产精品一区二区中文| 999久久久国产精品| 蜜臀91精品国产高清在线观看| 1000部精品久久久久久久久| 99视频在线精品国自产拍免费观看| 中文日韩欧美| 日本亚州欧洲精品不卡| 欧美另类中文字幕| 精品亚洲成人| 亚洲精品一级二级| 欧美日韩国产传媒| 亚洲一区国产一区| 日韩一区网站| 精品国产乱码久久久久久1区2匹| 麻豆mv在线观看| 国产高清一区| 午夜性色一区二区三区免费视频| 青青草精品视频| 精品久久视频| 亚洲国产专区| 亚洲3区在线| 开心激情综合| 欧美日韩国产传媒| 日韩高清在线不卡| av高清不卡| 久久福利一区| 日韩av电影一区| sm捆绑调教国产免费网站在线观看| 免费av一区| 国产欧美自拍一区| 中文字幕系列一区| 婷婷综合成人| 日本综合字幕| 免费精品视频在线| 成人精品国产亚洲| 玖玖精品视频| 成人亚洲一区| 欧美日韩四区| 欧美a级一区二区| 好看的亚洲午夜视频在线| 国产欧美日韩精品高清二区综合区| 精品久久91| 日韩中文字幕亚洲一区二区va在线| 欧美xxxx性| 久热综合在线亚洲精品| 久久精品系列| 一二三区精品| 超碰在线99| 综合亚洲视频| 久久天堂av| 欧美另类中文字幕| 欧美.日韩.国产.一区.二区| 国产图片一区| 91成人精品视频| 久久精品一区二区三区中文字幕| 免费成人网www| 国产调教精品| 最新日韩欧美| 极品av在线| 久久狠狠久久| 午夜在线播放视频欧美| 国产盗摄——sm在线视频| 日韩av二区在线播放| 午夜国产一区二区|