为什么要编写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. C++ Primer Plus 文章17章 进,输出和文件

    文章17章 进.输出和文件 1.当到达输入句子.他将刷新输出缓冲区满输出电流 2.streambuf分类 它提供了用于各种操作的一个缓冲 ios_base类表示流的一般特征 ios基础的类ios_ba ...

  2. Codeforces Round #191 (Div. 2)---A. Flipping Game

    Flipping Game time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  3. 虚拟化(一):虚拟化和vmware产品描述

    由于公司最近取得了虚拟化监控,因此,我们需要虚拟化的认识,总结学习,对于虚拟化的概念.从百度百科,例如下列:         虚拟化.是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上 ...

  4. JavaScript编写了一个计时器

    初学JavaScript,用JavaScript编写了一个计时器. 设计思想: 1.借助于Date()对象,来不断获取时间点: 2.然后用两次时间点的毫秒数相减,算出时间差: 3.累加时间差,这样就能 ...

  5. codeforces 438D

    在大大推荐下这个标题不明的人做.而我的最后一个非常喜欢的段树,因此,愤怒出手.认为基本上相同.大值,当最大值小于取模时能够剪枝. 今后再遇到此类问题算是能攻克了 // file name: d.cpp ...

  6. Ubuntu中编译链接Opencv应用的简便方式

    安装完毕Opencv后,使用下面命令查 看编译/连接參数 pkg-config --cflags --libs opencv 可看到例如以下信息 -I/usr/include/opencv  /usr ...

  7. eclipse 组态xdebug

    1.打开浏览器打开phpinfo页面视图PHP版本号.TS(线程安全)版本NTS(非线程安全)版本.以及VC6版本号是VC9版本号 2.和上面版本号相应的xdebug:http://xdebug.or ...

  8. 开发现代ASP.NET应用程序

    新思想.新技术.新架构——更好更快的开发现代ASP.NET应用程序(续1)   今天在@张善友和@田园里的蟋蟀的博客看到微软“.Net社区虚拟大会”dotnetConf2015的信息,感谢他们的真诚付 ...

  9. Swift语言指南(九)--基本运算符

    原文:Swift语言指南(九)--基本运算符 运算符(operator)是用来检查,改变或合并值的一种特殊符号或短语.例如,加号运算符让两个数字相加(如:let i = 1 + 2),还有些更复杂的运 ...

  10. dozer-初识

    1.简介     dozer是一种JavaBean的映射工具,类似于apache的BeanUtils.但是dozer更强大,它可以灵活的处理复杂类型之间的映射.不 但可以进行简单的属性映射.复杂的类型 ...