hash-3.hashCode
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的更多相关文章
- Hash和HashCode深入理解
目录介绍1.Hash的作用介绍1.1 Hash的定义1.2 Hash函数特性1.3 Hash的使用场景2.如何判断两个对象相等2.1 判断两个字符串2.2 判断两个int数值2.3 其他基本类型3.H ...
- Java中hashCode()方法以及HashMap()中hash()方法
Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...
- HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash
1.HashMap的内部实现机制 HashMap是对数据结构中哈希表(Hash Table)的实现,Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Value的数据结构,它通过一个映 ...
- Java基础知识点2:hashCode()方法
hashCode()方法基本实现 hashCode方法是Java的Object类所定义的几个基本方法之一.我们可以深入到Object类的源码中去查看: public native int hashCo ...
- 浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...
- hash算法总结收集
hash算法的意义在于提供了一种快速存取数据的方法,它用一种算法建立键值与真实值之间的对应关系,(每一个真实值只能有一个键值,但是一个键值可以对应多个真实值),这样可以快速在数组等条件中里面存取数据. ...
- Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实 ...
- 对hashmap与hashcode()、equals()的理解
1.equals方法没被重写的时候 比较的只是对象的地址 重写之后 比较的才是对象里的内容 2.重写equals的时候 务必需要重写hashcode 不然在用到容器的时候 会出现问题 因为容器会 ...
- hashmap的hash算法( 转)
HashMap 中hash table 定位算法: int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); 其中i ...
- HASH表原理(装)
HASH表原理 大家都知道,在所有的线性数据结构中,数组的定位速度最快,因为它可通过数组下标直接定位到相应的数组空间,就不需要一个个查找.而哈希表就是利用数组这个能够快速定位数据的结构解决以上的问题的 ...
随机推荐
- 【Alpha版本】 第七天 11.15
一.站立式会议照片: 二.项目燃尽图: 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 完成我要招聘的招聘详情显示,完成简历填写及显示功能 完成我要应聘的 ...
- #第一用Markdown编辑器#
Markdown初次使用 This is a simple Markdown editor based on 'Markdown' it's * italic * style. it's also _ ...
- C++ Primer Plus读书笔记
第五章 循环和关系表达式 1. 2.类别别名: (1) #define FLOAT_POINTER float * FLOAT_POINTER pa, pb; 预处理器置换将该声明转换成 flo ...
- java函数substring()
String str; str=str.substring(int beginIndex);截取掉str从首字母起长度为beginIndex的字符串,将剩余字符串赋值给str: str=str.sub ...
- asp.net与Matlab类型转换(待补全)
上上篇的博客已经提到如何配置环境,即如何在asp.net中调用matlab生成的dll文件.这篇博客打算做个笔记,那就是matlab和C#数据类型如何转换.随着需求的增加,我会不断增加新的类型转换. ...
- js时间戳转成日期不同格式 【函数】
//第一种 function getLocalTime(nS) { ).toLocaleString().replace(/:\d{,}$/,' '); } alert(getLocalTime()) ...
- Linux的95个小技巧
Linux的95个小技巧 by WEB全栈工程师 on 2012 年 03 月 27 日 这里总结了Linux使用中的一些小技巧 1.实现RedHat非正常关机的自动磁盘修复 先登录到服务器,然后在/ ...
- JavaWeb学习笔记——第一个JSP文件
必须加上第一句以用来指定编码,否则会出现乱码 <%@ page language="java" import="java.util.*" contentT ...
- Java适配器设计模式
适配器设计模式,一个接口首先被一个抽象类先实现(此抽象类通常称为适配器类),并在此抽象类中实现若干方法(但是这个抽象类中的方法体是空的),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法. ...
- 404. Sum of Left Leaves
Find the sum of all left leaves in a given binary tree. 左树的值(9+15=24) /** * Definition for a binary ...