1、有一个类Person,有两个字段age和name,我重写Object类的equal方法来比较两个对象的age和name是否相等,
但是不重写hashCode。

package com.hash;

public class Person {
private Integer age; private String name; public Person() {
super();
} public Person(Integer age, String name) {
super();
this.age = age;
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
} }

场景类

Person p1 = new Person(21,"tom");
Person p2 = new Person(21,"tom");
System.out.println(p1.equals(p2));

这样比较发现打印出来是true。然后执行下面的代码:

HashMap<Person,Integer> hp = new HashMap<Person,Integer>();
hp.put(p1, 10);
System.out.println(hp.get(p2));

发现打印出来是null,原因分析:

因这p1和p2只是逻辑上相等,但是它们的hashCode不相等,而hashMap往里面put对象的时
候,先获取key的hashcode,再往hash表中存数据
Person类没有重写hashCode方法,所以默认使用父类Object类的hashCode方法,是根据内存算的hashCode
,而p1和p2是在堆上new出的两个对象,二者的内存地址肯定不等,所以hashCode肯定不等,所以获取出来是null
要解决这个问题,只有重写hashCode方法,以确保当两个对象相同时,二者的hashCode必须相同

    @Override
public int hashCode(){
Integer prime = 31;
return prime*age.hashCode() + prime*name.hashCode();
}

重写hashCode方法后,再执行,发现打印出了10

2、

如果两个对象相同,那么二者hashCode必定相同,而hashCode相同,对象却不一定相同,因为散列函数计算hashCode的时候
可能会发生碰撞,如

hash类,我在这个类的hashCode方法里计算hashCode时,只是让age和name相加,这种hash算法,碰撞的机率非常大

package com.hash;

public class Hash {
private Integer age ; private Integer name; public Hash(Integer age, Integer name) {
super();
this.age = age;
this.name = name;
} public Hash() {
super();
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public Integer getName() {
return name;
} public void setName(Integer name) {
this.name = name;
} @Override
public int hashCode() {
final int prime = 31;
return prime*age+prime*name;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Hash other = (Hash) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
} }

场景类

//这就是hashCode产生碰撞,二者hashCode相同,而对象并不相等
Hash ha1 = new Hash(11,12);
Hash ha2 = new Hash(12,11); System.out.println(ha1.equals(ha2));
System.out.println("h1 hashCode="+ha1.hashCode()+",h2 hashCode="+ha2.hashCode());

虽然两个对象的hashCode相等,但是两个对象并不相等。

综上

(1)如果重写equal方法,则必须重写hashCode方法。

(2)两个对象相等,则二者hashCode必然相等。

(3)两个对象的hashCode相等,两个对象未必相等,因为计算的hashCode可能会碰撞。

hash-3.hashCode的更多相关文章

  1. Hash和HashCode深入理解

    目录介绍1.Hash的作用介绍1.1 Hash的定义1.2 Hash函数特性1.3 Hash的使用场景2.如何判断两个对象相等2.1 判断两个字符串2.2 判断两个int数值2.3 其他基本类型3.H ...

  2. Java中hashCode()方法以及HashMap()中hash()方法

    Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...

  3. HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash

    1.HashMap的内部实现机制 HashMap是对数据结构中哈希表(Hash Table)的实现,Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Value的数据结构,它通过一个映 ...

  4. Java基础知识点2:hashCode()方法

    hashCode()方法基本实现 hashCode方法是Java的Object类所定义的几个基本方法之一.我们可以深入到Object类的源码中去查看: public native int hashCo ...

  5. 浅谈Java中的hashcode方法

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

  6. hash算法总结收集

    hash算法的意义在于提供了一种快速存取数据的方法,它用一种算法建立键值与真实值之间的对应关系,(每一个真实值只能有一个键值,但是一个键值可以对应多个真实值),这样可以快速在数组等条件中里面存取数据. ...

  7. Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制

    HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实 ...

  8. 对hashmap与hashcode()、equals()的理解

    1.equals方法没被重写的时候   比较的只是对象的地址  重写之后 比较的才是对象里的内容 2.重写equals的时候 务必需要重写hashcode 不然在用到容器的时候 会出现问题 因为容器会 ...

  9. hashmap的hash算法( 转)

    HashMap 中hash table 定位算法: int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); 其中i ...

  10. HASH表原理(装)

    HASH表原理 大家都知道,在所有的线性数据结构中,数组的定位速度最快,因为它可通过数组下标直接定位到相应的数组空间,就不需要一个个查找.而哈希表就是利用数组这个能够快速定位数据的结构解决以上的问题的 ...

随机推荐

  1. Beta版本——第一次冲刺博客

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...

  2. js 递归下的循环

    的递归下的循环不能使用forEach  可以使用for代替 错误写法 // 获取完整名字 var getFullName = function(code, resultName) { if (code ...

  3. BZOJ4690: Never Wait for Weights

    裸带权并查集. #include<cstdio> #define N 100005 int m,i,j,s,t,u,d[N],p[N]; char k; int find(int i){ ...

  4. Maven中的dependencyManagement 意义

    1.在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器. 2.pom.xml文件中,jar的版本判断的两种途径 1:如果dependenci ...

  5. Spring浅探

    热度最大的框架,它也称为业务层框架.Spring这个框架的诞生,给程序员揭示了两个主要的思想:Ioc,Aop: 最近的网页架构可以分为这样. 传统结构中,每个层都得new出依赖层的类进行一些本层操作, ...

  6. win7下如何建立ftp服务器

    前段时间正在做一个项目,需要上传东西到ftp服务器,纠结于如何建立ftp服务器.经过一番摸索.终于成功建立ftp服务器.现将我的经验跟大家分享一下.不足之处还望多多指点! 步骤/方法 首先在本地机器上 ...

  7. 安装vim的ycm

    环境centos 6.7 vim 7.3 安装vundle Vundle(Vim bundle)是一个Vim的插件管理器.它是把git操作整合进去,用户需要做的只是去GitHub上找到自己想要的插件的 ...

  8. Java——不弹起的按钮组件:JToggleButton

    import java.awt.GridLayout; import javax.swing.JFrame; import javax.swing.JToggleButton; //========= ...

  9. (新手向)基于Bootstrap的简单轮播图的手机实现

    个人电脑里存了不少适合手机欣赏的图片,但是放手机里看是件很占据资源的事.鉴于家里有一台电脑经常开着,正好用来做家庭局域网共享,于是笔者就设想通过一种比较简单环保的思路.通过手机访问电脑内的图片. 首先 ...

  10. Unable to find vcvarsall.bat的解决办法

    明年绝对买MAC电脑,这一两天安装paramiko,真是操碎了心. 安装paramiko时报error: Unable to find vcvarsall.bat这种错误,网上找了各种方法啊,解决的办 ...