- 创建一个BloomFilter类
import java.util.BitSet;
import java.util.Random;
public class BloomFilter {
private BitSet bitSet;
private int bitSetSize = 2 << 24;
private int expectedNumberOfElements = 2000000;
private int numberOfHashFunctions;
private Random random = new Random();
public BloomFilter(int expectedNumberOfElements) {
if (expectedNumberOfElements > this.expectedNumberOfElements) {
this.expectedNumberOfElements = expectedNumberOfElements;
}
this.numberOfHashFunctions = (int) (Math.round(bitSetSize / expectedNumberOfElements) * Math.log(2.0));
this.bitSet = new BitSet(bitSetSize);
}
public void add(Object element) {
for (int i = 0; i < numberOfHashFunctions; i++) {
long hash = computeHash(element.toString(), i);
int index = getIndex(hash);
bitSet.set(index, true);
}
}
public boolean contains(Object element) {
for (int i = 0; i < numberOfHashFunctions; i++) {
long hash = computeHash(element.toString(), i);
int index = getIndex(hash);
if (!bitSet.get(index)) {
return false;
}
}
return true;
}
private int getIndex(long hash) {
return Math.abs((int) (hash % bitSetSize));
}
private long computeHash(String element, int seed) {
random.setSeed(seed);
byte[] data = element.getBytes();
long hash = 0x7f52bed27117b5efL;
for (byte b : data) {
hash ^= random.nextInt();
hash *= 0xcbf29ce484222325L;
hash ^= b;
}
return hash;
}
}
- 我这边主要是从MySQL中获取数据,加载到布隆过滤器中,并且每天进行一次更新。只供参考
@Component
@Slf4j
@EnableScheduling
public class UpdateBloomFilterTask {
@Autowired
private CommonService commonService;
private final int PAGE_SIZE = 1000;
@Scheduled(cron = "0 0 16 * * ?")
@Bean("bloomFilterClient")
public BloomFilter update() {
log.debug("bloomFilter init start");
List<String> data = commonService.getXXX(1, PAGE_SIZE);
BloomFilter bloomFilter = new BloomFilter(Math.toIntExact(data.size()));
for (String element : data) {
bloomFilter.add(element);
}
for (int i = 2; i <= data.getTotalPage(); i++) {
data = richMsgBlacklistService.getBlacklist(i, PAGE_SIZE);
for (String element : data) {
bloomFilter.add(element);
}
}
log.debug("bloomFilter init finish.");
return bloomFilter;
}
}
- 实现类进行使用
public class TestServiceImpl {
@Resource(name = "bloomFilterClient")
private BloomFilter bloomFilter;
public boolean testBloomFilter(String str) {
return bloomFilter.contains(str);
}
}