为什么要编写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方法的更多相关文章

  1. 如何编写出高质量的 equals 和 hashcode 方法?

    什么是 equals 和 hashcode 方法? 这要从 Object 类开始说起,我们知道 Object 类是 Java 的超类,每个类都直接或者间接的继承了 Object 类,在 Object ...

  2. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  3. 重新编写equals()方法,hashCode()方法,以及toString(),提供自定义的相等标准,以及自描述方法

    下面给出一个实例,重新编写equals()方法,提供自定义的相等标准 public class PersonTest { public static void main(String[] args) ...

  4. 重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源

    今天这篇文章我们打算来深度解读一下equal方法以及其关联方法hashCode(),我们准备从以下几点入手分析: 1.equals()的所属以及内部原理(即Object中equals方法的实现原理) ...

  5. 浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  6. 为什么重写equals时必须重写hashCode方法?

    原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...

  7. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  8. java的HashCode方法

    总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复: 后者元素无序,但元素不可重复. 要想保证元素不重复,可两个元素是 ...

  9. java中hashCode方法与equals方法的用法总结

    首先,想要明白hashCode的作用,必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重 ...

随机推荐

  1. (一)AngularJS获取贴纸Hello World

    一旦项目使用JQuery原创javascript,最近参加了一个项目,需要使用AngularJS.RequireJS比较框架,如汰渍. 这里写一些博客,记录自己的学习过程,虽然冠以原来的名字,资料,加 ...

  2. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    ...

  3. 经典弹出层Colorbox - a jQuery lightbox

    Colorbox - a jQuery lightbox A lightweight customizable lightbox plugin for jQuery Fork me on GitHub ...

  4. linux_安装 redis

    Installation Download, extract and compile Redis with: $ wget http://download.redis.io/releases/redi ...

  5. crawler_httpurlconnection_自动编码识别

    核心思想: 1:从响应头中读取 [命中解流准确率最高] 2:如果响应头中没有,打开流从源码中读取,[取舍,如果有一般在前30行会有,前100行中寻找] 3:如果还没有,根据字节码code位置,字符识别 ...

  6. python_在windows下安装配置python开发环境及Ulipad开发工具

    最近开始学习Python,在网上寻找一下比较好的IDE.因为以前用C#做开发的,用Visual Studio作为IDE,鉴于用惯了VS这么强大的IDE,所以对IDE有一定的依赖性. Python的ID ...

  7. C# Parse和Convert的区别分析(转)

    大家都知道在进行类型转换的时候有连个方法供我们使用就是Convert.to和*.Parse,但是疑问就是什么时候用C 什么时候用P 通俗的解释大家都知道: Convert 用来转换继承自object类 ...

  8. 教你一步一步部署.net免费空间OpenShift系列之一------帐号注册和验证

    前几天有博友发布了一篇文章<一键部署mono 免费空间支持ASP.NET MVC 再也不担心伙食费换空间了>,支持MVC3和域名绑定,觉得不错,于是自己实践了一下,发现自己实际遇到的问题真 ...

  9. 採用Hexo 搭建Team Blog

    採用Hexo 搭建Team Blog 首先你要会使用Git 已经GitHub,然后让我们了解下什么是静态Blog 静态博客是指 不须要数据库驱动,拥有丰富模板,通过模板标记语言生成简单html css ...

  10. PHP经验——获得PHP版本信息及版本比较

    原文:PHP经验--获得PHP版本信息及版本比较 偶然看到别人写的一句代码: <?php if (version_compare("5.2", PHP_VERSION, &q ...