hashCode和equal二三事
来源:互联网 发布:java物联网开发技术 编辑:程序博客网 时间:2024/04/19 23:55
关于equal经常用到,hashCode一直很抽象,很少用到,但又时时用到。
equals
有2个String
String s1 =new String( "aa");
String s2 = new String("bb");
s1.equals(s2); 输出true
有一个Student 类(没有重写equal方法) 2个对象
Student stu1 = new Student("张三");
Student stu2 = new Student("张三");
stu1.equals(stu2); 输出false;
同样是2组对象,为什么返回不一样呢?
所有类都继承了Object类,
因为String类本身已经重写了Object类中的equals方法,String调用equals方法时,比较的是他们的内容是否相等,s1和s2的内容相同,所以s1.equals(s2)为true。而且,String也重写了hashCode方法
而Student类没有重写Object类中的equals,而没有重写的Objec类中的equals方法比较的是2个对象的地址是否相同,stu1和stu2都是new 出来的对象,地址当然不同,所以
stu1.equals(stu2)为false
hashcode
hashcode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值。public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。
哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。
也就是说相互equals的两个对象,要保证他们的hashCode相同(使他们相同的原因主要是可以根据hashcode的值取的相应的对象,目的提高取对象的效率),
注意:但是在自定的类中如果只是重写了equals方法,却没有重写hashcode方法,就使得2个对象相互equals,但是他们的hashCode不一致(参见上一篇转载的博客)。
hash code是一种编码方式,在Java中,每个对象都会有一个hashcode,Java可以通过这个hashcode来识别一个对象。至于hashcode的具体编码方式,比较复杂(事实上这个编码是可以由程序员通过继承和接口的实现重写的)。而hashtable等结构,就是通过这个哈希实现快速查找键对象。这是他们的内部联系,但一般编程时无需了解这些,只要知道hashtable实现了一种无顺序的元素排列就可以了
查阅资料得到以下java语言的定义:
1) 对象相等则hashCode一定相等;
2) hashCode相等对象未必相等。
这也涉及到如何写自定义的hashCode方法的问题:必须符合以上条件。注意条件2中的未必。具体可参见java doc; Effective Java中有更详细论述
为什么要重写hashCode方法?
查看资料得知:
先了解java判断两个对象是否相等的规则
在java的集合中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等
1、如果不相等,认为两个对象也不相等,这也反面说明对象相等怎hashcode就相等。
2.1如果相等,则判断两个对象用equals运算是否相等(因为hashcode相等但是对象不一定相等,这时就要equals来判断了)
2.2如果不相等,认为两个对象也不相等
2.3如果相等,认为两个对象相等
有人会问既然最后还是靠equals判断对象是否相等,为什么还要用到hashCode呢,查阅资料和参看达人博客,本人得到下面的答案:
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率。在hashCode相同的情况下,再利用equals,总之一切都是为了效率
所以Java自定义了是可以根据hashCode直接判断2个对象是否相等,就要保证相互equals对象,他们的hashcode相等。所以简单来讲,hashcode相当于是一个对象的编码。
当要比较对象的内容而不比较引用时便重写equals方法 但重写equals方法便一定要重写hashcode方法,java机制会在调用equals方法时自动先调用hashcode方法
关于重写equals和hashCode方法给出一个例子
class Key { private Integer id; private String value; public Key(Integer id, String value) { super(); this.id = id; this.value = value; } @Override public boolean equals(Object o) { if(o == null || !(o instanceof Key_)) { //判断类型转换 return false; }else { return this.id.equals(((Key)o).id); //id相同则equals,则返回true。保证相同的key内容相同的对象相互equals } } @Override public int hashCode() { return id.hashCode(); //id是String类型,String重写了equals和hashCode,相同id,其hashcode一定相同 } }
关于hashCode的理解,也许会有失误,欢迎批评指正。
hashCode的作用参考:http://blog.csdn.net/chinayuan/article/details/3345559
- hashCode和equal二三事
- Hashcode, Equal和Dictionary
- HashCode和equal方法
- HashCode和equal方法
- 【转】 equal和hashcode
- HashCode和equal方法
- HashCode和equal方法
- HashCode和equal方法
- 重载equal和hashCode
- HashCode和equal方法
- hashCode和equal方法
- HashCode和equal方法
- HashCode和equal方法
- HashCode和equal
- 重载equal和hashCode
- HashCode和equal方法
- hashcode()和equal()
- equal和hashcode详解
- 谷歌笔试题-去除连续空格并翻转字符串
- 利用jquery cookie实现的简单换肤功能
- 浅谈业务建模一
- HDU-1518-square
- OGRE 动画
- hashCode和equal二三事
- ios 操作通讯录联系人(ABAddressBook用法)
- Spring与struts整合
- perl多线程实例(四个线程同时读MYSQL数据库获取记录)
- 国际化4
- 那年,我们在一起的故事
- 关于GAE中golang的context
- UVa 10192: Vacation
- 如何去掉CodeIgniter中URL里的index.php