原文链接 译文链接 译者:沈义扬
概述
Java内建的散列码[hash code]概念被限制为32位,并且没有分离散列算法和它们所作用的数据,因此很难用备选算法进行替换。此外,使用Java内建方法实现的散列码通常是劣质的,部分是因为它们最终都依赖于JDK类中已有的劣质散列码。
Object.hashCode往往很快,但是在预防碰撞上却很弱,也没有对分散性的预期。这使得它们很适合在散列表中运用,因为额外碰撞只会带来轻微的性能损失,同时差劲的分散性也可以容易地通过再散列来纠正(Java中所有合理的散列表都用了再散列方法)。然而,在简单散列表以外的散列运用中,Object.hashCode几乎总是达不到要求——因此,有了com.google.common.hash包。
散列包的组成
在这个包的Java doc中,我们可以看到很多不同的类,但是文档中没有明显地表明它们是怎样 一起配合工作的。在介绍散列包中的类之前,让我们先来看下面这段代码范例:
1
|
HashFunction hf = Hashing.md5();
|
2
|
HashCode hc = hf.newHasher()
|
4
|
.putString(name, Charsets.UTF_8)
|
5
|
.putObject(person, personFunnel)
|
HashFunction
HashFunction是一个单纯的(引用透明的)、无状态的方法,它把任意的数据块映射到固定数目的位指,并且保证相同的输入一定产生相同的输出,不同的输入尽可能产生不同的输出。
Hasher
HashFunction的实例可以提供有状态的Hasher,Hasher提供了流畅的语法把数据添加到散列运算,然后获取散列值。Hasher可以接受所有原生类型、字节数组、字节数组的片段、字符序列、特定字符集的字符序列等等,或者任何给定了Funnel实现的对象。
Hasher实现了PrimitiveSink接口,这个接口为接受原生类型流的对象定义了fluent风格的API
Funnel
Funnel描述了如何把一个具体的对象类型分解为原生字段值,从而写入PrimitiveSink。比如,如果我们有这样一个类:
3
|
final String firstName;
|
它对应的Funnel实现可能是:
01
|
Funnel<Person> personFunnel = new Funnel<Person>() {
|
03
|
public void funnel(Person person, PrimitiveSink into) {
|
06
|
.putString(person.firstName, Charsets.UTF_8)
|
07
|
.putString(person.lastName, Charsets.UTF_8)
|
注:putString(“abc”, Charsets.UTF_8).putString(“def”, Charsets.UTF_8)完全等同于putString(“ab”, Charsets.UTF_8).putString(“cdef”, Charsets.UTF_8),因为它们提供了相同的字节序列。这可能带来预料之外的散列冲突。增加某种形式的分隔符有助于消除散列冲突。
HashCode
一旦Hasher被赋予了所有输入,就可以通过hash()方法获取HashCode实例(多次调用hash()方法的结果是不确定的)。HashCode可以通过asInt()、asLong()、asBytes()方法来做相等性检测,此外,writeBytesTo(array, offset, maxLength)把散列值的前maxLength字节写入字节数组。
布鲁姆过滤器[BloomFilter]
布鲁姆过滤器是哈希运算的一项优雅运用,它可以简单地基于Object.hashCode()实现。简而言之,布鲁姆过滤器是一种概率数据结构,它允许你检测某个对象是一定不在过滤器中,还是可能已经添加到过滤器了。布鲁姆过滤器的维基页面对此作了全面的介绍,同时我们推荐github中的一个教程。
Guava散列包有一个内建的布鲁姆过滤器实现,你只要提供Funnel就可以使用它。你可以使用create(Funnel funnel, int expectedInsertions, double falsePositiveProbability)方法获取BloomFilter<T>,缺省误检率[falsePositiveProbability]为3%。BloomFilter<T>提供了boolean mightContain(T) 和void put(T),它们的含义都不言自明了。
01
|
BloomFilter<Person> friends = BloomFilter.create(personFunnel, 500 , 0.01 );
|
02
|
for (Person friend : friendsList) {
|
07
|
if (friends.mightContain(dude)) {
|
08
|
//dude不是朋友还运行到这里的概率为1%
|
09
|
//在这儿,我们可以在做进一步精确检查的同时触发一些异步加载
|
Hashing类
Hashing类提供了若干散列函数,以及运算HashCode对象的工具方法。
已提供的散列函数
md5()
|
murmur3_128()
|
murmur3_32()
|
sha1()
|
sha256()
|
sha512()
|
goodFastHash(int bits)
|
|
HashCode运算
方法
|
描述
|
HashCode combineOrdered( Iterable<HashCode>)
|
以有序方式联接散列码,如果两个散列集合用该方法联接出的散列码相同,那么散列集合的元素可能是顺序相等的
|
HashCode combineUnordered( Iterable<HashCode>)
|
以无序方式联接散列码,如果两个散列集合用该方法联接出的散列码相同,那么散列集合的元素可能在某种排序下是相等的
|
int consistentHash( HashCode, int buckets)
|
为给定的”桶”大小返回一致性哈希值。当”桶”增长时,该方法保证最小程度的一致性哈希值变化。详见一致性哈希。
|
原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: [Google Guava] 10-散列
from: http://ifeve.com/google-guava-hashing/
[Google Guava] 10-散列相关推荐
- Google Guava官方教程
原文链接 译文链接 译者: 沈义扬,罗立树,何一昕,*武祖 * 校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] . ...
- [转载]Google Guava官方教程(中文版)
原文链接 译文链接 译者: 沈义扬,罗立树,何一昕,武祖 校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓 ...
- Google Guava新手教程
以下资料整理自网络 一.Google Guava入门介绍 引言 Guavaproject包括了若干被Google的 Java项目广泛依赖 的核心库,比如:集合 [collections] .缓存 [c ...
- google guava 入门教程
Guava(瓜娃)学习笔记 (代码下载地址) Guava工程包含了若干被google的java项目广泛依赖的核心库,例如:集合 [collections] .缓存 [caching] .原生类型支持 ...
- Google Guava官方教程(中文版)gu
Google Guava官方教程(中文版) 原文链接 译文链接 译者: 沈义扬,罗立树,何一昕,武祖 校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ...
- Google Guava
转载自并发编程网 – ifeve.com 本文链接地址: Google Guava官方教程(中文版) 中文文档:http://ifeve.com/google-guava/ 开源地址:https:// ...
- 第10章 序列的修改、散列和切片
# <流畅的Python>读书笔记 # 第10章 序列的修改.散列和切片 转载于:https://www.cnblogs.com/larken/p/10576719.html
- Google Guava官方教程(中文版)
1. 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives sup ...
- 真正的缓存之王,Google Guava 只是弟弟
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://blog.csdn.net/a953713428/article/details/92159746 前面刚说到 ...
最新文章
- SpringBoot 使用(三): 配置文件详解
- 获取整数的位数_从NMEA0183到GNSS定位数据获取(二)软件篇
- 40. Combination Sum II **
- echart雷达图文字挤在一起_【数据可视化·图表篇】雷达图
- 月薪2500到年薪20万+,阿迪经历了些什么?
- python教程龟叔_Python新手入门
- java进入dos_java启动dos命令收集笔记一
- 辞退可以,暴力不行!
- c语言算法单循环球队比赛安排,单循环赛赛程安排算法研究.doc
- 深度学习领域堪称圣经的书籍(深度学习又称之为花书)-由图灵奖获得者Yoshua Bengio所著
- TunePat Amazon Video Downloader使用教程
- 黑马头条项目-Vue-day10-小智同学聊天功能,退出功能的实现,websocket用法,白名单,关于nextTick()方法
- qq公众平台出错了609_生鲜农贸行业订单容易出错,生鲜配送管理系统帮您来解决...
- 山东云则-您身边的物联网专家,助您快速接入物联网
- 线性回归梯度下降py实现
- vs2008安装boost库
- python自己做课程表_Python 大学生课表 iCalendar (.ics) 生成
- 认证、授权、鉴权、权限控制
- 计算机环模实验报告,PPT实验报告模板2篇
- vue3项目创建及请求配置
热门文章
- jboss7 加载module过程
- 王者荣耀全栈项目部署到阿里云服务器笔记
- LambdaMART简介——基于Ranklib源码(二 Regression Tree训练)
- 高德地图横屏不显示服务器,高德地图不能横屏!
- JVM - 剖析Java对象头Object Header之指针压缩
- MyBatis-24MyBatis缓存配置【集成EhCache】
- 复习笔记(三)——C++类和对象
- mysql特有语法_mysql 有用的特殊语法
- python 三数之和
- python查看方法作用_python学习笔记1,新手小白也能看得懂