Java中的hashCode二
来源:互联网 发布:windows snmp 编辑:程序博客网 时间:2024/05/22 13:30
equals方法和hashCode方法
在有些情况下,我们在设计一个类的时候,会重写equals 方法,比如String类,但是千万要注意,在重写equals 方法的同时,必须重写hashCode方法,为什么?
下面看一个例子:
package com.zd.test;public class People {private String name;private int age;public People(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic boolean equals(Object paramObject) {// TODO Auto-generated method stubif(this == paramObject){return true; //先检查是否其自反性,后比较paramObject是否为空。这样效率高}if(paramObject == null){return false;}if(paramObject instanceof People){People temp = (People)paramObject;if(temp.getName().equals(this.name) && temp.getAge() == this.age){return true;}else{return false;}}else{return false;}}}
package com.zd.test;import java.util.HashMap;public class Main {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubPeople p1 = new People("jack", 12);System.out.println(p1.hashCode());HashMap<People, Integer> hashMap = new HashMap<People, Integer>();hashMap.put(p1, 1);System.out.println(hashMap.get(new People("jack", 12)));}}
在这里只重写了equals 方法,也就是说如果俩个People对象,如果他们姓名和年龄相等,则认为同一个人。
这段代码的意愿是输出为“1”,但是事实上他输出为 “null“。为什么?原因就在于重写equals方法的同时没有重写hashCode方法。
虽然通过重写equals方法使得逻辑上姓名和年龄相同的俩个对象为相等的对象,但是要知道默认情况下,hashCode方法是将对象的存储地址进行映射。那么上述代码输出为
”null“就不奇怪了。原因很简单,p1指向对象和
System.out.println(hashMap.get(new People("jack", 12)));
这句话中的 new People("Jack", 12) 不是同一个对象,他们的存储地址肯定不同。
下面是HashMap的get方法的具体实现:
public V get(Object paramObject) { if (paramObject == null) { return getForNullKey(); } Entry localEntry = getEntry(paramObject); return null == localEntry ? null : localEntry.getValue(); }
所以在hashMap 进行get操作的时候,因为得到的hashcode值不同(注意:上述代码在某些情况下会得到相同的hashCode,不过这种概率比较小,因为虽然俩个对象的地
址不同,但是也有可能获得相同的hashCode),所以导致在get方法中for循环不会执行,直接返回null。
因此如果想要上述代码输出1 ,很简单,只要重写hashCode方法,让hashCode方法和equals 方法保持逻辑一致。
package com.zd.test;public class People {private String name;private int age;public People(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic int hashCode() {// TODO Auto-generated method stubreturn name.hashCode() * 37 + age;}@Overridepublic boolean equals(Object paramObject) {// TODO Auto-generated method stubif(this == paramObject){return true; //先检查是否其自反性,后比较paramObject是否为空。这样效率高}if(paramObject == null){return false;}if(paramObject instanceof People){People temp = (People)paramObject;if(temp.getName().equals(this.name) && temp.getAge() == this.age){return true;}else{return false;}}else{return false;}}}
在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一的返回一个整数。
如果俩个对象根据equals 方法比较是相等的,则hashCode方法不一定得返回相同的整数;
如果 俩个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。
设计hashCode时最重要的因素是:无论何时,对同一个对象调用hashCode都应该产生同样的值,如果在向一个Map中put时用的是一个值,而get的时候又是另一个值,那么
就无法获取到该对象了。
- Java中的hashCode二
- java中的hashcode
- java 中的hashcode&equals
- java中的hashCode方法
- java中的hashCode
- Java中的hashcode
- Java中的HashCode方法
- Java中的hashcode方法
- java中的hashcode方法
- Java中的HashCode
- Java中的hashcode方法
- java中的HashCode
- Java中的equals(),hashcode()
- Java 中的 hashcode一
- Java中的hashcode方法
- Java中的hashcode方法
- Java中的hashCode
- Java中的hashcode方法
- OC中的委托实例
- Catch That Cow
- 扩展型模式之Visitor(访问者)模式
- 辉光特效
- bzoj3930【CQOI2015】选数
- Java中的hashCode二
- Bencode的编码与解码
- 解决pip install 时locale.Error: unsupported locale setting
- android面试经典(6)
- c++作业3
- [前端 2]常用的JQuery和Dom页面取值与赋值
- 关于Opencv编程入门的基础知识点
- centos 安装htop
- 130. Surrounded Regions