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表原理 大家都知道,在所有的线性数据结构中,数组的定位速度最快,因为它可通过数组下标直接定位到相应的数组空间,就不需要一个个查找.而哈希表就是利用数组这个能够快速定位数据的结构解决以上的问题的 ...
随机推荐
- requst方法简单用一下
使用getParametar() 获取表单提交过来的文本框的值 setAttribute(String name, Object o)存储此请求中的属性.在请求之间重置属性.此方法常常与 Reques ...
- Android系统手机端抓包方法
抓包准备 1. Android手机需要先获得root权限.一种是否获得root权限的检验方法:安装并打开终端模拟器(可通过安卓市场等渠道获得).在终端模拟器界面输入su并回车,若报错则说明未root, ...
- 常见linux命令释义(第三天)
今天晚上看鸟哥的私房菜,边学边写笔记. 在linux中压缩大多是.tar, .tar.gz , .tgz, /gz, .bz2等. .gz 是通过gzip压缩的文件. .bz2 是通过bzip2压缩的 ...
- iOS - 类簇
类簇是在Objective-C中Foundation Framework中广泛使用的一种设计模式 1.发现类簇(Class Cluster)的踪迹 //*> 执行下面代码 id obj1 = [ ...
- MooseFs-分布式文件系统系列(四)之简单聊聊MFS的日常维护
回顾 文件或目录的额外属性(noower,noattracache和noentrycache),可以通过MFS提供的命令(mfsgeteattr,mfsseteattr,mfsdeleattr等)检查 ...
- python学习笔记-(十)面向对象基础
面向对象相关知识简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义 ...
- SQL日期格式转换
CONVERT(nvarchar(20), [Date],101) as 'Date' 10/20/2016 CONVERT(nvarchar(20), [Date],102) as 'Date ...
- Unity Serialization
http://forum.unity3d.com/threads/serialization-best-practices-megapost.155352/ http://docs.unity3d.c ...
- Linux基础整理-软件的安装与卸载
redhat/centos/fedora/suse系列: 摘自网址:http://www.runoob.com/linux/linux-yum.html yum( Yellow dog Updater ...
- createStatement()的用法
createStatement()的用法 标签: 数据库concurrencyscrollsql 2012-02-24 19:58 2508人阅读 评论(0) 收藏 举报 分类: JavaEE服务器 ...