最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的布隆過(guò)濾器你真的懂了嗎

 更新時(shí)間:2023年04月26日 17:15:02   作者:平凡一只濤  
經(jīng)常會(huì)聽到大家說(shuō)起布隆過(guò)濾器,但是很多人都只是聽過(guò)名字,卻并不知道其是怎么實(shí)現(xiàn)的。下面將詳細(xì)介紹一下布隆過(guò)濾器,并且使用簡(jiǎn)單的代碼演示

什么是布隆過(guò)濾器

布隆過(guò)濾器(Bloom Filter)是一種空間效率非常高的隨機(jī)數(shù)據(jù)結(jié)構(gòu),它利用位數(shù)組(BitSet)表示一個(gè)集合,并通過(guò)一定數(shù)量的哈希函數(shù)將元素映射為位數(shù)組中的位置,用于檢查一個(gè)元素是否屬于這個(gè)集合。

實(shí)現(xiàn)的核心思想

對(duì)于一個(gè)元素,通過(guò)多個(gè)哈希函數(shù)生成多個(gè)哈希值,將對(duì)應(yīng)的位在位數(shù)組中設(shè)為 1,若多個(gè)哈希值對(duì)應(yīng)的位都為 1,則認(rèn)為該元素可能在集合中;若至少有一個(gè)哈希值對(duì)應(yīng)的位為 0,則該元素一定不在集合中。這種方法可以在較小的空間中實(shí)現(xiàn)高效的查找,但可能存在誤判率(false positive)。

怎么理解

一個(gè)典型的布隆過(guò)濾器包含三個(gè)參數(shù): 位數(shù)組的大?。创鎯?chǔ)元素的個(gè)數(shù)); 哈希函數(shù)的個(gè)數(shù); 填充因子(即誤判率),即將元素?cái)?shù)量與位數(shù)組大小的比值。

如上圖所示: 布隆過(guò)濾器的基本操作流程,包括初始化位數(shù)組和哈希函數(shù)、插入元素、檢查元素是否在集合中等。其中,每個(gè)元素都會(huì)被多個(gè)哈希函數(shù)映射到位數(shù)組中的多個(gè)位置,而在檢查元素是否在集合中時(shí),需要確保所有對(duì)應(yīng)的位都被設(shè)置為 1,才會(huì)認(rèn)為該元素可能在集合中。

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

垃圾郵件過(guò)濾: 將所有的黑名單郵件對(duì)應(yīng)的哈希值在布隆過(guò)濾器中對(duì)應(yīng)的位置設(shè)為 1,對(duì)于每一封新郵件,將其哈希值在布隆過(guò)濾器中對(duì)應(yīng)的位置檢查是否都為 1,若是,則認(rèn)為該郵件是垃圾郵件,否則可能是正常郵件;

URL 去重: 將已經(jīng)抓取的 URL 對(duì)應(yīng)的哈希值在布隆過(guò)濾器中對(duì)應(yīng)的位置設(shè)為 1,對(duì)于每一條新的 URL,將其哈希值在布隆過(guò)濾器中對(duì)應(yīng)的位置檢查是否都為 1,若是,則認(rèn)為該 URL 已經(jīng)抓取過(guò),否則需要進(jìn)行抓??;

緩存擊穿: 將緩存中存在的所有數(shù)據(jù)對(duì)應(yīng)的哈希值在布隆過(guò)濾器中對(duì)應(yīng)的位置設(shè)為 1,對(duì)于每一個(gè)查詢的鍵值,將其哈希值在布隆過(guò)濾器中對(duì)應(yīng)的位置檢查是否都為 1,若是,則認(rèn)為該鍵值存在于緩存中,否則需要從數(shù)據(jù)庫(kù)中查詢并將其添加到緩存中。

需要注意的是,布隆過(guò)濾器的誤判率會(huì)隨著位數(shù)組大小的增加而減小,但同時(shí)也會(huì)增加內(nèi)存開銷和計(jì)算時(shí)間。 為了方便理解布隆過(guò)濾器,下面用java代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)單的布隆過(guò)濾器:

import java.util.BitSet;
import java.util.Random;
public class BloomFilter {
??private BitSet bitSet; ??????????// 位集,用于存儲(chǔ)哈希值
??private int bitSetSize; ????????// 位集大小
??private int numHashFunctions; ??// 哈希函數(shù)數(shù)量
??private Random random; ?????????// 隨機(jī)數(shù)生成器
??// 構(gòu)造函數(shù),根據(jù)期望元素?cái)?shù)量和錯(cuò)誤率計(jì)算位集大小和哈希函數(shù)數(shù)量
??public BloomFilter(int expectedNumItems, double falsePositiveRate) {
????this.bitSetSize = optimalBitSetSize(expectedNumItems, falsePositiveRate);
????this.numHashFunctions = optimalNumHashFunctions(expectedNumItems, bitSetSize);
????this.bitSet = new BitSet(bitSetSize);
????this.random = new Random();
??}
??// 根據(jù)期望元素?cái)?shù)量和錯(cuò)誤率計(jì)算最佳位集大小
??private int optimalBitSetSize(int expectedNumItems, double falsePositiveRate) {
????int bitSetSize = (int) Math.ceil(expectedNumItems * (-Math.log(falsePositiveRate) / Math.pow(Math.log(2), 2)));
????return bitSetSize;
??}
??// 根據(jù)期望元素?cái)?shù)量和位集大小計(jì)算最佳哈希函數(shù)數(shù)量
??private int optimalNumHashFunctions(int expectedNumItems, int bitSetSize) {
????int numHashFunctions = (int) Math.ceil((bitSetSize / expectedNumItems) * Math.log(2));
????return numHashFunctions;
??}
??// 添加元素到布隆過(guò)濾器中
??public void add(String item) {
????// 計(jì)算哈希值
????int[] hashes = createHashes(item.getBytes(), numHashFunctions);
????// 將哈希值對(duì)應(yīng)的位設(shè)置為 true
????for (int hash : hashes) {
??????bitSet.set(Math.abs(hash % bitSetSize), true);
????}
??}
??// 檢查元素是否存在于布隆過(guò)濾器中
??public boolean contains(String item) {
????// 計(jì)算哈希值
????int[] hashes = createHashes(item.getBytes(), numHashFunctions);
????// 檢查哈希值對(duì)應(yīng)的位是否都為 true
????for (int hash : hashes) {
??????if (!bitSet.get(Math.abs(hash % bitSetSize))) {
????????return false;
??????}
????}
????return true;
??}
??// 計(jì)算給定數(shù)據(jù)的哈希值
??private int[] createHashes(byte[] data, int numHashes) {
????int[] hashes = new int[numHashes];
????int hash1 = Math.abs(random.nextInt());
????int hash2 = Math.abs(random.nextInt());
????for (int i = 0; i < numHashes; i++) {
??????// 使用兩個(gè)隨機(jī)哈希函數(shù)計(jì)算哈希值
??????hashes[i] = Math.abs((hash1 * i) + (hash2 * i) + i) % data.length;
????}
????return hashes;
??}
}

以上就是Java中的布隆過(guò)濾器你真的懂了嗎的詳細(xì)內(nèi)容,更多關(guān)于Java布隆過(guò)濾器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot修改內(nèi)置Tomcat默認(rèn)端口號(hào)的示例

    Spring Boot修改內(nèi)置Tomcat默認(rèn)端口號(hào)的示例

    本篇文章主要介紹了Spring Boot修改內(nèi)置Tomcat端口號(hào)的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java 圖片壓縮實(shí)現(xiàn)思路及代碼

    Java 圖片壓縮實(shí)現(xiàn)思路及代碼

    本文為大家詳細(xì)介紹下圖片壓縮的具體實(shí)現(xiàn)思路及java代碼,想學(xué)習(xí)的各位可以參考下哈,希望對(duì)大家有所幫助
    2013-07-07
  • SpringBoot中使用監(jiān)聽器的方法詳解

    SpringBoot中使用監(jiān)聽器的方法詳解

    這篇文章主要為大家詳細(xì)介紹了SpringBoot中使用監(jiān)聽器的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • java 壓縮圖片(只縮小體積,不更改圖片尺寸)的示例

    java 壓縮圖片(只縮小體積,不更改圖片尺寸)的示例

    這篇文章主要介紹了java 如何壓縮圖片體積,幫助大家更好的利用Java處理圖片,應(yīng)對(duì)特殊情況,感興趣的朋友可以了解下
    2020-10-10
  • Java的LinkedHashMap的實(shí)現(xiàn)原理詳解

    Java的LinkedHashMap的實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了Java的LinkedHashMap的實(shí)現(xiàn)原理詳解,???LinkedHashMap是Map接口的哈希表和鏈接列表實(shí)現(xiàn),具有可預(yù)知的迭代順序,此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用null值和null鍵,此類不保證映射的順序,特別是它不保證該順序恒久不變,需要的朋友可以參考下
    2023-09-09
  • Java中Stream的flatMap與map使用場(chǎng)景及區(qū)別詳解

    Java中Stream的flatMap與map使用場(chǎng)景及區(qū)別詳解

    這篇文章主要介紹了Java中Stream的flatMap與map使用場(chǎng)景及區(qū)別詳解,Stream 流式操作,一般用于操作集合即 List 一類的數(shù)據(jù)結(jié)構(gòu),簡(jiǎn)單來(lái)說(shuō) Stream 的 map 使得其中的元素轉(zhuǎn)為另一種元素的映射(map)方法,需要的朋友可以參考下
    2024-01-01
  • 淺談Maven包沖突的原理及解決方法

    淺談Maven包沖突的原理及解決方法

    這篇文章主要介紹了淺談Maven包沖突的原理及解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • java不同線程解讀以及線程池的使用方式

    java不同線程解讀以及線程池的使用方式

    這篇文章主要介紹了java不同線程解讀以及線程池的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • maven繼承父工程統(tǒng)一版本號(hào)的實(shí)現(xiàn)

    maven繼承父工程統(tǒng)一版本號(hào)的實(shí)現(xiàn)

    這篇文章主要介紹了maven繼承父工程統(tǒng)一版本號(hào)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java中indexOf()方法詳解及其日常使用舉例

    Java中indexOf()方法詳解及其日常使用舉例

    這篇文章主要給大家介紹了關(guān)于Java中indexOf()方法詳解及其日常使用舉例的相關(guān)資料,indexOf()方法是JavaScript字符串的內(nèi)置方法之一,它用于查找給定子字符串在原始字符串中第一次出現(xiàn)的位置,需要的朋友可以參考下
    2023-12-12

最新評(píng)論

皋兰县| 定日县| 建宁县| 平泉县| 上杭县| 辉县市| 应城市| 商城县| 天门市| 汉寿县| 武平县| 依兰县| 顺义区| 富民县| 通州市| 通道| 山阴县| 得荣县| 兴安县| 漠河县| 沙雅县| 株洲市| 屯门区| 龙口市| 富民县| 东宁县| 柳州市| 娱乐| 张家界市| 高州市| 巨鹿县| 崇阳县| 东莞市| 丹巴县| 措勤县| 密云县| 芜湖市| 武鸣县| 丁青县| 同心县| 华阴市|