赞
踩
Java 中 BitSet就是“位图”数据结构 (可以简单看做redis的bitmaps数据结构),根据“位图”的语义,数据的存在性可以使用 bit 位上的1或0来表示;一个 bit 具有2个值:0和1,正好可以用来表示 false 和 true。
可以使用BitSet实现一个简单的布隆过滤器,判断“数据是否存在”。
package com.wuxiaolong.algorithm.bloomfilter; import org.apache.commons.lang3.StringUtils; import java.util.BitSet; //布隆过滤器 public class BloomFilter { /* BitSet初始分配2^24个bit */ private static final int DEFAULT_SIZE = 2 << 24; /** 不同哈希函数的种子,一般应取质数 * 质数又叫素数,指的是在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。反之,则被称为合数。 * 1和0既非素数,也非合数。 * 质数有无穷个,主要有2、3、5、7、11、13、17、19、23、29、31、37、41、43、47、53、59、61、67、71等。 * 质数的性质: * 1、质数p的约数只有两个,分别是1和p。 * 2、初等数学基本定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。 * 3、质数的个数是无限的。 * 4、质数的个数公式π(n)是不减函数。 * */ private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37 }; /** * JAVA中BitSet就是“位图”数据结构,根据“位图”的语义, * 数据的存在性可以使用bit位上的1或0来表示;一个bit具有2个值:0和1,正好可以用来表示false和true */ private BitSet bits = new BitSet(DEFAULT_SIZE); /* 哈希函数对象 */ private SimpleHash[] func = new SimpleHash[seeds.length]; public BloomFilter() { for (int i = 0; i < seeds.length; i++) { func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]); } } // 将url标记到bits中 public void add(String str) { for (SimpleHash f : func) { bits.set(f.hash(str), true); } } // 判断是否已经被bits标记 public boolean contains(String str) { if (StringUtils.isBlank(str)) { return false; } boolean ret = true; for (SimpleHash f : func) { ret = ret && bits.get(f.hash(str)); } return ret; } /* 哈希函数类 */ public static class SimpleHash { private int cap; private int seed; public SimpleHash(int cap, int seed) { this.cap = cap; this.seed = seed; } // hash函数,采用简单的加权和hash public int hash(String value) { int result = 0; int len = value.length(); for (int i = 0; i < len; i++) { result = seed * result + value.charAt(i); } // 计算取模结果: result % cap // 当取模运算 取模的数字cap是2的n方时 可以转换成二进制的按位与 : result & (cap-1) return result & (cap - 1); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。