guava笔记11-Hashing

阅读更多

一.Guava提供了一些方法帮助我们生成hash值。

主要有下面几个帮助类:

HashFunction: hash函数,可以用于创建Hasher对象

Hashing:定义了一些hash函数,主要有md5(),murmur3_128(),murmur3_32(),sha1(),sha256(),sha512(),goodFastHash(int bits)。

Hasher:计算hash值,提供了putXxx()方法用于添加数据,以及hash()方法返回计算结果HashCode。

HashCode:hash值计算结果

Funnel:定义了怎样将一个Object对象分解为primitive 类型,Hasher的putObject方法需要传入这样的对象。

 

示例:

class Person {

  final int id;

  final String firstName;

  final String lastName;

  final int birthYear;

}

 

//Funnel定义了Person对象如何分解为primitive 类型,以便Hasher的putObject方式使用

Funnel personFunnel = new Funnel() {

  @Override

  public void funnel(Person person, PrimitiveSink into) {

    into

      .putInt(person.id)

      .putString(person.firstName, Charsets.UTF_8)

      .putString(person.lastName, Charsets.UTF_8)

      .putInt(birthYear);

  }

};

 

HashFunction hf = Hashing.md5();

HashCode hc = hf.newHasher()

       .putLong(id)

       .putString(name, Charsets.UTF_8)

       .putObject(person, personFunnel) //putObject方法

       .hash();

System.out.println(hc. asInt ());  //hash结果输出

System.out.println(hc. asBytes());  //hash结果输出

 

二.  BloomFilter

BloomFilter是一种算法,用于判断一个对象是否包含在一个集合里面。这种做法只需要占用很低的空间,效率也非常高。但是判断结果会有一定的误差。

大概实现方式为:

1.       先定义一个n位的二进制数组。

2.       对任意一个对象,采用m种hash函数计算它的hash值,得到的每个hash值映射到数组的某一位,把二进制数组的这一位就标记为1。

3.       判断一个对象是否包含在集合中时,采用同样的m种hash函数计算hash值,同样映射到数组中的位,如果这些位全部为1,则表示该对象确实很可能包含于集合中,只要有一位不为1,则该对象一定不包含于集合中。

 

自从Burton Bloom在70年代提出Bloom Filter之后,Bloom Filter就被广泛用于拼写检查和数据库系统中。近一二十年,伴随着网络的普及和发展,Bloom Filter在网络领域获得了新生,各种Bloom Filter变种和新的应用不断出现。

 

这种做法适用于能够容忍一定的错误率的场景。Guava中的BloomFilter实现了这种算法。

BloomFilter friends = BloomFilter.create(personFunnel, 500, 0.01);

for(Person friend : friendsList) {

  friends.put(friend);

}

// much later

if (friends.mightContain(dude)) {

  // the probability that dude reached this place if he isn't a friend is 1%

  // we might, for example, start asynchronously loading things for dude while we do a more expensive exact check

}

 

BloomFilter.create方法创建了BloomFilter对象,三个参数分别指定了Object分解为primitive 的方式(因为Hasher.putObject方法需要这个参数),集合的预期大小,以及容错率。

BloomFilter的hash函数策略目前只有一种BloomFilterStrategies. MURMUR128_MITZ_32,它可以根据你期望的集合大小和容错率来计划hash函数的个数及二进制数组的大小。

BloomFilter.put方法可以将对象放到集合中

BloomFilter. mightContain用于判断对象是否可能包含于集合中

BloomFilter. expectedFpp用于得到目前的错误率(这个不一定跟create方法传入的容错率参数相等,因为目前加入集合中的元素个数不一定等于crate方法传入的预期元素个数)

 

你可能感兴趣的:(guava笔记11-Hashing)