算法比較複雜,也不是本文研究的範疇,直接使用已有的實現。
java
google的guava包中提供了BloomFilter類,咱們直接使用它來進行一下簡單的測試。 新建一個maven工程,引入guava包(建議你們使用這個包,裏面有不少google封裝好的代碼);算法
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>22.0</version>
</dependency>
</dependencies>
複製代碼
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.util.ArrayList;
import java.util.List;
public class Test {
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);
}
for (int i = 0; i < size; i++) {
if (!bloomFilter.mightContain(i)) {
System.out.println("有壞人逃脫了");
}
}
List<Integer> list = new ArrayList<Integer>(1000);
for (int i = size + 10000; i < size + 20000; i++) {
if (bloomFilter.mightContain(i)) {
list.add(i);
}
}
System.out.println("有誤傷的數量:" + list.size());
}
}
複製代碼
運行後發現,沒有壞人逃脫,當咱們去遍歷這一百萬個數時,他們都在過濾器內被識別了出來。數組
誤傷的數量是330.也就是有330個不在過濾器內的值,被認爲在過濾器裏,被誤傷了。錯誤機率是3%做用,爲啥是3%呢。bash
在create的多個重載方法中,最終走的是有4個參數的那個。咱們上面用的是有2個參數的,注意看圖片最下面,咱們不填第三方參數時,默認補了一個0.03,這個就表明了容許的錯誤機率是3%。第四個參數是哈希算法,默認是BloomFilterStrategies.MURMUR128_MITZ_64。maven
在第127行能夠看到,要存下這一百萬個數,位數組的大小是7298440,700多萬位,實際上要完整存下100萬個數,一個int是4字節32位,咱們須要4X8X1000000=3千2百萬位,差很少只用了1/5的容量,若是是HashMap,按HashMap 50%的存儲效率,咱們須要6千4百萬位,全部布隆過濾器佔用空間很小,只有HashMap的1/10-1/5做用。函數
128行是hash函數的數量,是5,也就是說系統以爲要保證3%的錯誤率,須要5個函數外加700多萬位便可。用3%偏差換十分之一的內存佔用。測試
咱們也能夠修改這個錯誤機率,譬如咱們改成0.0001萬分之一。google
private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0001);
複製代碼
以上是布隆過濾器的簡單使用。具體的應用場景,具體實現。spa