目录
【散列】
散列码也可称作哈希函数,即我们在存储数据时,数据和关键字是按照一定的规律存放,以便在查找时能按照这样的规律高效准确的找到对应记录,这里的规律就是由哈希函数确定的。
JDK对于散列码并没有提供很好有效的方法,因此Guava开发了HashFunction专门对哈希函数的使用进行了封装。
一、HashFunction
HashFunction是一个单纯的(引用透明的)、无状态的方法,它把任意的数据块映射到固定数目的位置,并且保证相同的输入一定产生相同的输出,不同的输入尽可能产生不同的输出。
二、Hashing
Hashing类提供了若干散列函数,返回HashFunction,供进行操作。
- | - | - | - |
---|---|---|---|
md5() | murmur3_128() | murmur3_32() | sha1() |
sha256() | sha512() | goodFastHash(int bits) |
三、Hasher
HashFunction的实例可以提供有状态的Hasher,Hasher提供了流畅的语法把数据添加到散列运算,然后获取散列值。Hasher可以接受所有原生类型、字节数组、字节数组的片段、字符序列、特定字符集的字符序列等等,或者任何给定了Funnel实现的对象。
四、HashCode
一旦Hasher被赋予了所有输入,就可以通过hash()方法获取HashCode实例(多次调用hash()方法的结果是不确定的)。HashCode可以通过asInt()、asLong()、asBytes()方法来做相等性检测,此外,writeBytesTo(array, offset, maxLength)把散列值的前maxLength字节写入字节数组。
// md5加密,生成某字符串的哈希码
public static String md5(String key) {
HashFunction md5 = Hashing.md5();
Hasher hasher = md5.newHasher();
HashCode hashCode = hasher.putString(key, Charsets.UTF_8).hash();
return hashCode;
}
五、Funnel
Funnel描述了如何把一个具体的对象类型分解为原生字段值,从而写入PrimitiveSink。(PrimitiveSink接口,接受原始类型的数据,作为Hash函数的入参)
六、BloomFilter
布鲁姆过滤器是一种概率数据结构,它允许你检测某个对象是一定不在过滤器中,还是可能已经添加到过滤器了。
public static void FunnelTest() {
Funnel<Student> funnel = new Funnel<Student>() {
@Override
public void funnel(Student from, PrimitiveSink into) {
into.putInt(from.getId())
.putString(from.getName(), Charsets.UTF_8)
.putChar(from.getGender());
}
};
// 缺省误检率为5%
BloomFilter.create(funnel, 5);
}
// class Student
public class Student {
private int id;
private String name;
private char gender;
// Getter and Setter
}
补充:
HashCode运算
方法 | 描述 |
---|---|
HashCode combineOrdered(Iterable<HashCode>) | 以有序方式联接散列码,如果两个散列集合用该方法联接出的散列码相同,那么散列集合的元素可能是顺序相等的 |
HashCode combineUnordered(Iterable<HashCode>) | 以无序方式联接散列码,如果两个散列集合用该方法联接出的散列码相同,那么散列集合的元素可能在某种排序下是相等的 |
int consistentHash(HashCode, int buckets) | 为给定的”桶”大小返回一致性哈希值。当”桶”增长时,该方法保证最小程度的一致性哈希值变化。 |