我们HashMap会有一个rehash的过程,为什么呢?因为java内建的散列码被限制为32位,而且没有分离散列算法和所作用的数据,所以替代算法比较难做。我们使用HashMap的时候它自身有一个rehash的过程,所以我们无需操心。但是如果我们自己离开hashmap的内容,去使用Object.hashCode()就不有可能会比较坑爹了,碰撞处理我们自己去做并不容易。但是,我们可以使用Guava的hash功能。
Guava的Hash package底下的内容比较多:
它提供了不同的Hash算的实现,然后我们需要先从继承体系上面去看一下。
Hash算法的继承体系:
Function函数的继承体系:
然后还有Funnel接口等,基本上已经包括Hash的组成内容,下面我们挨个来看下都是做什么的。
/**
* An object which can receive a stream of primitive values.
@Beta
public interface PrimitiveSink {···}------------------一个能接收原始数据类型流的对象?
里面定义了一堆方法,都是putxxxxvalue:
PrimitiveSink putBytes(byte[] bytes, int off, int len); PrimitiveSink putShort(short s); PrimitiveSink putInt(int i); PrimitiveSink putLong(long l); PrimitiveSink putFloat(float f); PrimitiveSink putDouble(double d); PrimitiveSink putBoolean(boolean b); PrimitiveSink putChar(char c); PrimitiveSink putUnencodedChars(CharSequence charSequence); PrimitiveSink putString(CharSequence charSequence, Charset charset);
非常好理解,不赘述。然后我们看Hasher这个核心类(接口)是干啥的:
@Beta
public interface Hasher extends PrimitiveSink {
@Override
Hasher putByte(byte b); @Override
Hasher putBytes(byte[] bytes);
}
好吧,其实它就是把PrimitiveSink的方法给全部override了一遍,然后它新增了几个方法:
<T> Hasher putObject(T instance, Funnel<? super T> funnel);------------一个简化的put object进行hash的方法 @CheckReturnValue
HashCode hash();---实际做hash的方法 @Override
@Deprecated
int hashCode();----不推荐使用,但是必须覆盖的hashcode
上个代码示例:
package com.congsg.learning; import com.google.common.base.Charsets;
import com.google.common.hash.*; import java.nio.charset.Charset; /**
* Created by congshaogang on 16/3/29.
*/
public class GuavaHashTest { public static void main(String[] args) { HashFunction function_0 = Hashing.md5();
HashFunction function_1 = Hashing.murmur3_128();
Hasher hasher_0 = function_0.newHasher();
Hasher hasher_1 = function_1.newHasher(); Person person = new Person();
person.setAge(27);
person.setName("hahahah");
person.setAddress("北京三里屯");
person.setPhoneNumber(16666666666L);
person.setMale(Male.man); HashCode code_0 = hasher_0.putInt(person.getAge())
.putString(person.getName(), Charsets.UTF_8)
.putString(person.getAddress(), Charsets.UTF_8)
.putLong(person.getPhoneNumber())
.putObject(person.getMale(), new Funnel<Male>() {
@Override
public void funnel(Male from, PrimitiveSink into) {
into.putString(from.name(),Charsets.UTF_8);
}
}).hash();
HashCode code_1 = hasher_1.putInt(person.getAge())
.putString(person.getName(), Charsets.UTF_8)
.putString(person.getAddress(), Charsets.UTF_8)
.putLong(person.getPhoneNumber())
.putObject(person.getMale(), new Funnel<Male>() {
@Override
public void funnel(Male from, PrimitiveSink into) {
into.putString(from.name(),Charsets.UTF_8);
}
}).hash();
System.out.println(code_0.asLong());
System.out.println(code_1.asLong());
} public enum Male {
man, woman;
} public static class Person {
int age;
String name;
String address;
long phoneNumber;
Male male; public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} public long getPhoneNumber() {
return phoneNumber;
} public void setPhoneNumber(long phoneNumber) {
this.phoneNumber = phoneNumber;
} public Male getMale() {
return male;
} public void setMale(Male male) {
this.male = male;
}
}
}
我们可以利用自己去构造一些primitive的数据类型去进行hash操作,最后获得hash值。
Guava包学习--Hash的更多相关文章
-
Guava包学习---Lists
Guava包是我最近项目中同事推荐使用的,是google推出的库.里面的功能非常多,包括了集合.缓存.原生类型支持.并发库.通用注解.字符串处理.IO等.我们项目中使用到了guava依赖,但是实际上只 ...
-
Guava包学习--EventBus
之前没用过这个EventBus,然后看了一下EventBus的源码也没看明白,(-__-)b.反正大概就是弄一个优雅的方式实现了观察者模式吧.慢慢深入学习一下. 观察者模式其实就是生产者消费者的一个变 ...
-
Guava包学习---I/O
Guava的I/O平时使用不太多,目前项目原因导致基本上只有在自己写一些文本处理小工具才用得到.但是I/O始终是程序猿最常遇到的需求和面试必问的知识点之一.同时Guava的I/O主要面向是时JDK5和 ...
-
Guava包学习-Cache
这段时间用到了ehcache和memcache,memcache只用来配置在tomcat中做负载均衡过程中的session共享,然后ehcache用来存放需要的程序中缓存. Guava中的Cache和 ...
-
Guava包学习---Maps
Maps包方法列表: 还是泛型创建Map: public static <K, V> HashMap<K, V> newHashMap() { return new HashM ...
-
Guava包学习--Table
Table,顾名思义,就好像HTML中的Table元素一样,其实就是行+列去确定的值,更准确的比喻其实就是一个二维矩阵. 其实它就是通过行+列两个key去找到一个value,然后它又containsv ...
-
Guava包学习---Bimap
Bimap也是Guava中提供的新集合类,别名叫做双向map,就是key->value,value->key,也就是你可以通过key定位value,也可以用value定位key. 这个场景 ...
-
Guava包学习-Multimap
它和上一章的MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset. Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同v ...
-
Guava包学习---Sets
Sets包的内容和上一篇中的Lists没有什么大的区别,里面有些细节可以看一下: 开始的创建newHashSet()的各个重载方法.newConcurrentHashSet()的重载方法.newTre ...
随机推荐
-
谈谈JS中的函数节流
好吧,一直在秋招中,都没怎么写博客了...今天赶紧来补一补才行...我发现,在面试中,讲到函数节流好像可以加分,尽管这并不是特别高深的技术,下面就聊聊吧! ^_^ 备注:以下内容部分来自<Jav ...
-
javascript的defer和async的区别。
我们常用的script标签,有两个和性能.js文件下载执行相关的属性:defer和async defer的含义[摘自https://developer.mozilla.org/En/HTML/Elem ...
-
Drools 查询学习
Drools 查询学习查询以 query 关键字开始,以 end 关键字结束,在 package 当中一个查询要有唯一的名称,查询的内容就是查询的条件部分,条件部分内容的写法与规则的 LHS 部分写法 ...
-
php数组常见的几种遍历方法
1.foreach遍历 $arr[] = array('first'=>green,'second'=>'yellow','third'=>'blue'); foreach($arr ...
-
java servlet手机app访问接口(四)推送
一. 服务端DEMO下载及运行. 登录友盟后,浏览器直接输入下面这个URL,直接进入文档开发和DEMO下载页面:http://dev.umeng.com/push/ios/integration(下面 ...
-
计算机视觉:关于视觉算法源码中常出现的imageLib库的使用指南
1.ReadImage(CImage &im, char* path)/ WriteImage(CImage &im, char* path) (1)将im强制转换为CByteImag ...
-
UVa247 Calling Circles
Time Limit: 3000MS 64bit IO Format: %lld & %llu map存人名,floyd传递闭包,DFS查询. 输出答案的逗号后面还有个空格,被坑到了2 ...
-
Linux编程---线程
首先说一下线程的概念.事实上就是运行在进程的上下文环境中的一个运行流.普通进程仅仅有一条运行流,可是线程提供了多种运行的路径并行的局面. 同一时候,线程还分为核心级线程和用户级线程.主要差别在属于核内 ...
-
[阿当视频]WEB组件学习笔记
— 视频看完了,自定义事件还不懂,等完全懂了再更新并完成整篇案例 1. JS分层和组件的种类浏览器底层包括HTML CSS JS(DOM/BOM/Style/Canvas 2D/WebGl/SVG) ...
-
LINUX 笔记-文件隐藏属性
chmod u+s xxx 设置setuid(4775) chmod g+s xxx 设置gid(2775) chmod o+t xxx 设置stick bit,针对目录(1775)