布隆过滤器判断一个元素存在就是判断对应位置是否为`1`来确定的,但是如果要删除掉一个元素是不能直接把`1`改成`0`的,因为这个位置可能存在其它元素,所以如果要支持删除,那我们应该怎么做呢? 最简单的做法就是加一个计数器,就是说位数组的每个位如果不存在就是`0`,存在几个元素就存具体的数字,而不仅仅只是存`1`。那么这就有一个问题,本来存`1`就是一位就可以满足了,但是如果要存具体的数字比如说`2`,那就需要`2`位了,所以**带有计数器的布隆过滤器会占用更大的空间**。 #### 带有计数器的布隆过滤器 带有计数器的布隆过滤器目前也已经被实现了,下面就是一个带有计数器的布隆过滤器示例: 1. 继续在`pom.xml`文件引入下面依赖: ~~~java <dependency> <groupId>com.baqend</groupId> <artifactId>bloom-filter</artifactId> <version>1.0.7</version> </dependency> ~~~ 2. 在`src/main/java`目录下的`com.lonely.wolf.redis`包内新建一个带有计数器的布隆过滤器`CountingBloomFilter.java`(这里计数器空间大小传了`8`,即最多允许`255`次重复,如果不传的话这里默认是`16`位大小,即允许`65535`次重复。): ~~~java package com.lonely.wolf.redis; import orestes.bloomfilter.FilterBuilder; public class CountingBloomFilter { public static void main(String[] args) { //初始化一个带有计数器的布隆过滤器 //第一个参数是存入数据量,第二个参数是fpp,第三个是带计数器的过滤器中每个空间占用大小 orestes.bloomfilter.CountingBloomFilter<String> cbf = new FilterBuilder(1000000, 0.01).countingBits(8).buildCountingBloomFilter(); cbf.add("zhangsan"); cbf.add("lisi"); cbf.add("wangwu"); System.out.println("是否存在王五:" + cbf.contains("wangwu")); //true cbf.remove("wangwu");//删除wangwu System.out.println("是否存在王五:" + cbf.contains("wangwu")); //false } } ~~~ 3. 同时,需要修改`pom.xml`文件中的`mainClass`属性,把这个类名修改正确: ~~~xml <mainClass>com.lonely.wolf.redis.CountingBloomFilter</mainClass> ~~~ 4. 执行如下命令: ~~~bash # 进入主目录 cd /home/project/redis-demo # 将项目打包成一个 jar 包 mvn clean package -Dmaven.test.skip=true # 运行 java -jar target/redis-demo-1.0.0-SNAPSHOT.jar ~~~ 运行之后效果如下图所示,可以看到元素被成功删除: ![](https://img.kancloud.cn/bd/92/bd927c1d26f9d22b860a9b2451c97420_735x117.png)