hashcode与equals的一些事

  有时候一些东西不经意听见了,并不当回事,回头就忘了。人总是这么健忘!

  学习hebernate的时候,看到一句话,对于需要映射到数据库中的实体类需要满足几个要求,其中有一个是说对于重写了equals重写后要重写hashcode。相信这是一句老生常谈的话了,大家都不陌生。当时我也一扫而过。后来看到一个短片说怎样验证一个cookie有效性也提到了hash算法。于是就想验证一下之前的两个重写。

  当时随手就写了一段代码(没有用快捷键),如下:

 1 public class hash {
 2     public static void main(String[] args) {
 3
 4         HashSet<Student> hs = new HashSet<Student>();
 5         Student stu1 = new Student("zhang");
 6         Student stu2 = new Student("zhang");
 7
 8         hs.add(stu1);
 9         hs.add(stu2);
10         System.out.println(hs.size());
11     }
12 }
13
14 class Student {
15     String name;
16
17     Student( String name) {
18         this.name = name;
19     }
20
21 //    @Override
22 //    public int hashCode() {
23 //        // TODO Auto-generated method stub
24 //        final int INDEX = 12345;
25 //        return name.hashCode()*INDEX;
26 //    }假若不覆盖hashcode方法会怎样啦!将会发现两个对象stu1和stu2我们期望是同一个,不用存进来了,但是在hash值这一关就没有过,new对象时默认以对象的内存地址映射hash值,也就是new了两个对象的hash值是不同的,
27
28     //因此我们需要覆盖hashcode(),让它按我们的期望来返回hash值
29
30     public int hashcode() {
31
32         final int INDEX = 12345;
33         return name.hashCode()*INDEX;
34     }
35
36
37     public boolean equals(Student stu ) {
38
39         if(this.name.equals(stu.name)){
40             return true;
41         }
42         return false;
43     }
44 }

  我期望是结果是set中只插入一个,但结果总是两个,搞得我都有点怀疑set插入的判断过程了,难道不是像记忆中的那样首先判断hash值,如果相等就判断equals,若equals相等就是说明是同一个,就不插入吗!郁闷了半天搞得。后来我说打印一下hash值看一下啦,结果吓我一大跳,怎么有两个.hashcode()方法,难道是我眼花吗,再仔细一看,打自己耳光的心都有,怎么可以将hashCode()写成hashcode(),赶紧改过来,但还是不对,问题又在哪里啦,这不是坑吗,短短的几行代码,为什么就是不能按我的想法来啦,郁闷。一共就两个方法,那在看看是不是equals啦,好吧,懒得自己写了,还是用快捷键了,一个alt+shift+s,覆盖equals看看,结果又让我不爽了,我的刚才的那个equals怎么就是Student参数啦,好吧,对自己无语了(说到这里就顺带说一下overload和override,前者是在同一个类中根据参数的不同重载,后面的是子类覆盖父类的方法,除了方法体里的东西不一样外,其余的都一样)。赶快修改过来,再运行,出现了自己想要的结果。

 1 public class hash {
 2     public static void main(String[] args) {
 3
 4         HashSet<Student> hs = new HashSet<Student>();
 5         Student stu1 = new Student("zhang");
 6         Student stu2 = new Student("zhang");
 7
 8         hs.add(stu1);
 9         hs.add(stu2);
10         System.out.println(hs.size());
11     }
12 }
13
14 class Student {
15     String name;
16
17     Student( String name) {
18         this.name = name;
19     }
20
21 //    @Override
22 //    public int hashCode() {
23 //        // TODO Auto-generated method stub
24 //        final int INDEX = 12345;
25 //        return name.hashCode()*INDEX;
26 //    }假若不覆盖hashcode方法会怎样啦!将会发现两个对象stu1和stu2我们期望是同一个,不用存进来了,但是在hash值这一关就没有过,new对象时默认以对象的内存地址映射hash值,也就是new了两个对象的hash值是不同的,
27
28     //因此我们需要覆盖hashcode(),让它按我们的期望来返回hash值
29     @Override
30     public int hashCode() {
31         // TODO Auto-generated method stub
32         final int INDEX = 12345;
33         return name.hashCode()*INDEX;
34     }
35
36     @Override
37     public boolean equals(Object obj) {
38         // TODO Auto-generated method stub
39         Student stu =(Student)obj;
40         if(this.name.equals(stu.name)){
41             return true;
42         }
43         return false;
44     }
45 }

  下面就说说如果我们不覆盖hashcode会是什么后果啦。按照我们的想法,stu1和stu2有同样的名字是同一个人,我们希望不要同时都放到set中,但是我们如果不覆盖hashcode,在new对象的时候就会将对象的内存地址映射成hash值,就会导致两个对象拥有不同的hash值,当然这不是我们想要的结果,所以我们需要覆盖上诉的两个方法次啊是完整的。

时间: 2024-11-13 04:23:20

hashcode与equals的一些事的相关文章

java 中hashcode和equals 总结

一.概述            在Java中hashCode的实现总是伴随着equals,他们是紧密配合的,你要是自己设计了其中一个,就要设计另外一个.当然在多数情况下,这两个方法是不用我们考虑的,直接使用默认方法就可以帮助我们解决很多问题.但是在有些情况,我们必须要自己动手来实现它,才能确保程序更好的运作. 1.1 规则 粗略总结一下在JavaDoc中所规定hashcode方法的合约:      Objects that are equal must have the same hash co

hashcode和equals

在java中,万物皆对象,所有的对象都继承于Object类,Object类有两个方法equals和hashCode.equals一般用来比较两个对象的内容是否相等,而hashCode一般用来提高容器的查询效率. public native int hashCode(); public boolean equals(Object obj) { return (this == obj); } equals在没有重写的情况下和==是一样的,对于值类型,比较的是值,对于引用类型则比较的是对象的首地址.

hashCode与equals

很多东西都是大处显积累,小处见功力,来点功力. hashCode跟equals 相伴相生,所以要一起讨论才有意义. 在java中,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,就是说当集合中插入对象时,怎么分辨该对象是否已经存在.按照正常思路,应该是依次进行equals比较,但是其实效率不高,java中的做法是先比较hashCode,如果相同在equals比较,到这里,疑问就出来了,为什么会比较hashCode,hashCode相同的情况下为什么equals为什么还会不同?

Object对象详解(三)之hashCode与equals

从学习Java开始,就从各个师兄.各种书籍.各大网站听到.看到,重写equals方法必须重写hashCode方法.重写equals方法必须重写hashCode方法.重写equals方法必须重写hashCode方法. 那么为什么呢?今天就详细剖析一下equals和hashCode! equals方法是比较两个对象实例是否相等.Object中equals方法的描述为: public boolean equals(Object obj) { return (this == obj); } 也就是默认情

重写hashCode与equals方法的作用

为了阐明其作用,我们先来假设有如下一个Person类. class Person { public Person(String name, int age) { this.name = name; this.age = age; } private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; }

java 小结3 hashcode和equals I/o问题

我需要把星期天看的一些东西记录下来,要不然会忘记. hashCode.equals: 1)每个java对象都有hashCode和equals方法. java的终极类是object类,那么object类是如何来标注自己呢,就是object这个类是如何来区分对方.就是使用它们的hashcode和equals来推断. (hashcode是通过hash算法实现的) 2)JVM每new一个object,都会讲Object丢到一个Hash(哈希表)里去,这样下次比较或者获取这个对象的时候就可以根据对象的ha

key的hashcode与equals方法改写

get方法过程:首先计算key的hashcode,找到数组中对应位置的某一元素,然后通过key的equeals方法在对应的链表中找到需要的元素.所以,hashcode与equals方法对于找到对应元素是两个关键的方法. HsahMap的key可以是任何类型,例如User对象,为了保证两个具有相同属性的User对象的hashcode相同,我们需要改写hashcode方法,比方说把hashcode的值的计算与User对象的id关联起来,那么只要user对象拥有相同的id,那么他们的hashcode就

Java基础:hashCode与equals个人学习记录

摘要: 本文主要记录本人对hashCode和对equals两个知识点的学习过程. 从学生时期初学java,就知道hashCode和equals这两个方法,工作中equals方法使用也是特别频繁,要说equals方法,那么必须少不了hashCode这个方法.下面就整理一下本人目前对这俩方法的理解,文中如有错误,请指正,多谢. hash code(散列码,也可以叫哈希码值)是对象产生的一个整型值.其生成没有规律的.二者散列码可以获取对象中的信息,转成那个对象的"相对唯一"的整型值.所有对象

hashcode和equals方法

分析: 1:Person类 1:姓名和年龄 2:重写hashCode和equals方法 1:如果不重写,调用Object类的equals方法,判断内存地址,为false 1:如果是Person类对象,并且姓名和年龄相同就返回true 2:如果不重写,调用父类hashCode方法 1:如果equals方法相同,那么hashCode也要相同,需要重写hashCode方法 3:重写toString方法 1:不重写,直接调用Object类的toString方法,打印该对象的内存地址 Person类 cl