我们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的更多相关文章

  1. Guava包学习---Lists

    Guava包是我最近项目中同事推荐使用的,是google推出的库.里面的功能非常多,包括了集合.缓存.原生类型支持.并发库.通用注解.字符串处理.IO等.我们项目中使用到了guava依赖,但是实际上只 ...

  2. Guava包学习--EventBus

    之前没用过这个EventBus,然后看了一下EventBus的源码也没看明白,(-__-)b.反正大概就是弄一个优雅的方式实现了观察者模式吧.慢慢深入学习一下. 观察者模式其实就是生产者消费者的一个变 ...

  3. Guava包学习---I/O

    Guava的I/O平时使用不太多,目前项目原因导致基本上只有在自己写一些文本处理小工具才用得到.但是I/O始终是程序猿最常遇到的需求和面试必问的知识点之一.同时Guava的I/O主要面向是时JDK5和 ...

  4. Guava包学习-Cache

    这段时间用到了ehcache和memcache,memcache只用来配置在tomcat中做负载均衡过程中的session共享,然后ehcache用来存放需要的程序中缓存. Guava中的Cache和 ...

  5. Guava包学习---Maps

    Maps包方法列表: 还是泛型创建Map: public static <K, V> HashMap<K, V> newHashMap() { return new HashM ...

  6. Guava包学习--Table

    Table,顾名思义,就好像HTML中的Table元素一样,其实就是行+列去确定的值,更准确的比喻其实就是一个二维矩阵. 其实它就是通过行+列两个key去找到一个value,然后它又containsv ...

  7. Guava包学习---Bimap

    Bimap也是Guava中提供的新集合类,别名叫做双向map,就是key->value,value->key,也就是你可以通过key定位value,也可以用value定位key. 这个场景 ...

  8. Guava包学习-Multimap

    它和上一章的MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset. Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同v ...

  9. Guava包学习---Sets

    Sets包的内容和上一篇中的Lists没有什么大的区别,里面有些细节可以看一下: 开始的创建newHashSet()的各个重载方法.newConcurrentHashSet()的重载方法.newTre ...

随机推荐

  1. Jsp&Servlet入门级项目全程实录第6讲

    惯例广告一发,对于初学真,真的很有用www.java1234.com,去试试吧! 1.建立数据表及数据(略) 2.创建student model package com.java1234.model; ...

  2. COM线程模型的行为

    原文:https://msdn.microsoft.com/library/ms809971.aspx Behavior of the COM Threading Models COM线程模型的行为 ...

  3. 哪个类可用于处理 Unicode?

    A. InputStreanReader的构造函数: InputStreamReader(InputStream in)          创建一个使用默认字符集的 InputStreamReader ...

  4. wcf和webapi(转)

    WCF 1.这个也是基于SOAP的,数据格式是XML 2.这个是Web Service(ASMX)的进化版,可以支持各种各样的协议,像TCP,HTTP,HTTPS,Named Pipes, MSMQ. ...

  5. 使用 Vuejs 开发 chrome 插件的注意事项

    使用 Vuejs 开发 chrome 插件 chrome 插件的开发其实并不难,web开发者可以使用 html, css, javascript 轻松的开发实用的 chrome 插件. 一个好的 ch ...

  6. ASP.NET SignalR-B.S/C.S 相互打通DEMO

    ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.   什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知 ...

  7. Git Client 管理:项目文件的获取和提交(实用篇)

    Git 服务器 可搭在云端如:coding.net.GitHub.TFS等,只要可以使用Git就可以. 示例: Git Client 安装相关程序,顺序如下: 1.安装Git-2.14.2.3-64- ...

  8. display:table-cell实现水平垂直居中

    如果查看css手册,会发现display有许多带table字样的可选属性,有table.inline-table.table-row-group.table-row.table-cell等10个之多, ...

  9. sql 单表查询练习

    -- 工资高于3000的员工select * from emp where sal > 3000;-- 工资在2500和3000之间的员工select * from emp where sal ...

  10. logback总结

    Logback Logback由三大模块组成:logback-core.logback- classic和logback-access. Logback-core是其它两个模块的基础模块. Logba ...