编写简单的hashCode方法
为什么要编写hashCode方法
hashCode在平时不常自己去编写,但是在真正高质量的代码中却是必不可少的。
看看Java中的Object对hashCode方法的描述:
1.返回对象的哈希码,是为了提高哈希表的性能,例如java.util.HashTable
2.同一个对象多次调用hashCode方法时,必须一致的返回相同的整数
3.若两个对象相等,则调用hashCode方法的时候必须返回相同的整数
不编写hashCode方法出现的情况
下面有这样的一个实体类:
/**
* @class User
* @introduction 实体类
* @author Ray_xujianguo
*/
public class User {
private String name; //姓名
private int age; //年龄
private long friendNumber; //朋友数目
private float cash; //现金
private double wealth; //财富
private boolean isMarry; //是否已婚 //无参数构造方法
public User() {} //有参数构造方法
public User(String name, int age, long friendNumber, float cash, double wealth, boolean isMarry) {
this.name = name;
this.age = age;
this.friendNumber = friendNumber;
this.cash = cash;
this.wealth = wealth;
this.isMarry = isMarry;
} @Override
public boolean equals(Object object) {
if(object instanceof User) {
User user = (User)object;
if(user.getName().equals(name) &&
user.getAge() == age &&
Long.compare(user.getFriendNumber(), friendNumber) == 0 &&
Float.compare(user.getCash(), cash) == 0 &&
Double.compare(user.getWealth(), wealth) == 0 &&
user.isMarry() == isMarry) {
return true;
} else {
return false;
}
} else {
return false;
}
} //getter and setter method
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public long getFriendNumber() {
return friendNumber;
} public void setFriendNumber(long friendNumber) {
this.friendNumber = friendNumber;
} public float getCash() {
return cash;
} public void setCash(float cash) {
this.cash = cash;
} public double getWealth() {
return wealth;
} public void setWealth(double wealth) {
this.wealth = wealth;
} public boolean isMarry() {
return isMarry;
} public void setMarry(boolean isMarry) {
this.isMarry = isMarry;
}
}
这个实体类是重写了equals方法的,现在我们试图将其放进Map中,再将其拿出来。
@Test
public void testHashCode() {
Map<User, String> map = new HashMap<User, String>();
map.put(new User("xujianguo", 21, (long)1000, (float)12.5, (double)6000.25, false), "admin");
System.out.println(map.get(new User("xujianguo", 21, (long)1000, (float)12.5, (double)6000.25, false)));
}
这个的map存进去了一个User和String啊,根据这个User怎么拿不到呢,原因是因为这两个User的hashCode不一样,说到根本的东西就是调用hashCode方法没有返回一致的哈希码下面我们就来说说怎么编写hashCode方法。
编写hashCode方法
1.把某个非零的常数值,保存在一个名为result的int类型的常量中
2.属性域f哈希码c的计算
- 如果是boolean类型,true为1,false为0
- 如果是byte、char、short和int类型,强制为int的值
- 如果是long类型,计算(int)(f^(f>>32))
- 如果是float类型,计算Float.floatToIntBits(f)
- 如果是double类型,计算Double.doubleToLongBits(f),再按照long的方法进行计算
- 如果是引用类型,则调用其hashCode方法(假设其hashCode满足你的需求)
3.代入公式result = result * 31 + c
4.返回result
现在针对这User类来编写hashCode方法:
@Override
public int hashCode() {
int result = 17;
result = 37 * result + name.hashCode();
result = 37 * result + age;
result = 37 * result + (int)(friendNumber^(friendNumber>>32));
result = 37 * result + Float.floatToIntBits(cash);
result = 37 * result + (int)(Double.doubleToLongBits(wealth)^(Double.doubleToLongBits(wealth)>>32));
result = 37 * result + (isMarry ? 1 : 0);
return result;
}
加入了这个hashCode方法后,上面那个testHashCode方法就可以成功通过key拿出value了。
编写简单的hashCode方法的更多相关文章
- 如何编写出高质量的 equals 和 hashcode 方法?
什么是 equals 和 hashcode 方法? 这要从 Object 类开始说起,我们知道 Object 类是 Java 的超类,每个类都直接或者间接的继承了 Object 类,在 Object ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 重新编写equals()方法,hashCode()方法,以及toString(),提供自定义的相等标准,以及自描述方法
下面给出一个实例,重新编写equals()方法,提供自定义的相等标准 public class PersonTest { public static void main(String[] args) ...
- 重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源
今天这篇文章我们打算来深度解读一下equal方法以及其关联方法hashCode(),我们准备从以下几点入手分析: 1.equals()的所属以及内部原理(即Object中equals方法的实现原理) ...
- 浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...
- 为什么重写equals时必须重写hashCode方法?
原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- java的HashCode方法
总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复: 后者元素无序,但元素不可重复. 要想保证元素不重复,可两个元素是 ...
- java中hashCode方法与equals方法的用法总结
首先,想要明白hashCode的作用,必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重 ...
随机推荐
- hdu 4915 Parenthese sequence--2014 Multi-University Training Contest 5
主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4915 Parenthese sequence Time Limit: 2000/1000 MS (Ja ...
- Repository模式
Repository模式的两种写法与疑惑 现如今DDD越来越流行,园子里漫天都是介绍关于它的文章.说到DDD就不能不提Repository模式了,有的地方也叫它仓储模式. 很多时候我们对Reposit ...
- 朴素UNIX之-打开历史
它可以毫不夸张地说,,UNIX模型是现代操作系统的原型.无论是真实的UNIX让我们大系列AIX,Solaris,HP-UX,FreeBSD,NetBSD,...或类别UNIX实例Linux...或基于 ...
- java学习笔记1——window7下JDK环境变量配置图解
1. 首先下载Java安装工具包 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...
- GitBook配置
GitBook 是一个通过 Git 和 Markdown 来撰写书籍的工具.生成格式有:JSON.ePub.PDF.Website ! ================================ ...
- mysql 千分位 Format
原文:mysql 千分位 Format select Format(123456789) 结果:123,456,789
- UVa 11121 - Base -2
题目:计算以-2为基数的数的表示. 分析:数论.写出不同位数能表示的数字区间就能够找到规律. 长度为1:[1,1]: 长度为2:[-2,-1]: 长度为3:[2,5]: 观察发现,区间长度增长为1,2 ...
- Android 4.4堆叠结构的变化
我们知道,activity 在 AMS 的形式是 ActivityRecord,task 在 AMS 的形式TaskRecord,流程 AMS 该管理形式 ProcessRecord. 我们先看下 4 ...
- 【 D3.js 进阶系列 — 5.0 】 直方图
直方图用于描写叙述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据. 假设有数组 a = [10, 11, 11.5, 12.5, 13, 15, 19, 20 ],如今把10~2 ...
- 全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org
先给出官网地址:deflang.org 一句话简介:可扩展编程语言 Def 的目标是将 C++ 的高效抽象和 Lisp 的强大表现力融为一体. 你可以通过阅读 入门教程 .源码 或 测试用例 来简要或 ...