`
chroya
  • 浏览: 656656 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

自定义对象需要重写hashcode

阅读更多

      Java中的很多对象都override了equals方法,都知道,这是为了能比较两个对象是否相等而定义,如果不需要比较,则不需要定义equals方法。比如StringBuffer类,没有提供equals方法,则说明没有两个StringBuffer对象是相等的。再比如Collections类,全部是静态方法,根本没必要创建对象,所以也就没有提供equals方法。
      我们程序中自定义的对象有时候需要比较它们是否相等,也需要重写equals方法。如果我们要将对象放到HashMap或者Hashtable这样的hash集合中的时候,就需要重写hashcode方法了。因为它们是根据hashcode来标识对象的。
      如果我们不重写hashcode方法,把他们作为key放入hashmap中是什么情况呢?看看下面代码:

import java.util.HashMap;

public class HashTest {

	public static void main(String...args) {
		MyBean a = new MyBean();
		a.x = 1;
		a.s = "xyz";
		MyBean b = new MyBean();
		b.x = 1;
		b.s = "xyz";
		HashMap<MyBean, String> map = new HashMap<MyBean, String>();
		map.put(a, "a");
		map.put(b, "b");
		System.out.println("a equals b:"+a.equals(b));
		System.out.println("map size:"+map.size());
		System.out.println("a:"+map.get(a));
		System.out.println("b:"+map.get(b));
	}
}

class MyBean {
	int x;
	String s;
	@Override
	public boolean equals(Object obj) {		
		if(this == obj) return true;
		if(!(obj instanceof MyBean)) return false;
		if(((MyBean)obj).x == x) return true;
		return false;
	}
}

      结果如下:

a equals b:true
map size:2
a:a
b:b  

      a和b明明是相等的,可是放进hashmap中之后,却被认为是两个对象,很诡异哦。
      下面加上hashcode,再看看什么结果:

class MyBean {
	int x;
	String s;
	@Override
	public boolean equals(Object obj) {		
		if(this == obj) return true;
		if(!(obj instanceof MyBean)) return false;
		if(((MyBean)obj).x == x) return true;
		return false;
	}
	@Override
	public int hashCode() {
		return (s!=null?s.hashCode():1)*31+x;
	}
}

     结果如下:

a equals b:true
map size:1
a:b
b:b

 

      这样才保证了相等的对象在hash集合中也相等。计算hashcode的时候,一般使用关键的属性的hashcode值。计算hashcode的属性较多则计算复杂,降低了效率,若较少的属性计算,则重复的hashcode较多,同样降低性能,写一个好的hashcode方法,还比较难。
      所以,我们重写equals的时候,一定要重写hashcode方法。

分享到:
评论

相关推荐

    实验05 Java集合.doc

    注意:因为Person类是自定义类,需要重写hashCode()方法和equals()方法,并规定只有姓名和身份证号都相等,则对象相等。 其中计算哈希码的算法:(31 + ((name == null) ? 0 : name.hashCode()))*31 + id (注:...

    涵盖了90%以上的面试题

    为什么重写equals还要重写hashCode? 介绍一下volatile jdk1.5新特性 jdk1.7新特性 jdk1.8新特性 java语言有哪些优点? 同一个.java文件中是否可以有多个main方法 一个".java"源文件中是否可以包括多个类(不是内部类...

    java培训机构内部预习文档

    面向对象三大特性 封装、继承、多态、对象创建过程、访问修饰符、super关键字、方法重写、instanceof chp8.三个修饰符 static、final、abstract chp9.接口 基本语法、接口的作用、解耦合 chp10.常用类 内部类、...

    javaSE代码实例

    14.2.2 重写hashCode方法 275 14.3 集合框架的层次结构 -277 14.4 Ordered与Sorted的接口 278 14.4.1 Ordered的排序 278 14.4.2 Sorted的排序 279 14.5 列表 279 14.5.1 列表接口——st 279 14.5.2 ...

    疯狂JAVA讲义

    学生提问:使用组合关系来实现复用时,需要创建两个Animal对象,是不是意味着使用组合关系时系统开销更大? 159 5.9 初始化块 159 5.9.1 使用初始化块 160 5.9.2 初始化块和构造器 161 5.9.3 静态初始化块 162 ...

    JAVA基础课程讲义

    equals和hashcode方法 143  泛型 144 思考作业 145 上机作业 145 第八章 IO技术 146 为什么需要学习IO技术 146 基本概念 146 数据源 146 流的概念 146 第一个简单的IO流程序及深入(将文件中的数据读入) 146 Java...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例106 简化hashCode()方法的重写 130 实例107 使用字符串输出对象 132 实例108 简化toString()方法的重写 133 5.6 克隆与序列化 134 实例109 Java对象的假克隆 134 实例110 Java对象的浅克隆 135 实例111 Java对象...

    Java学习笔记-个人整理的

    {3.1.3}\ttfamily hashCode}{68}{subsection.3.1.3} {3.2}String类}{69}{section.3.2} {3.3}String常量重利用}{70}{section.3.3} {3.4}正则表达式}{71}{section.3.4} {3.5}StringBuffer}{75}{section.3.5} {...

Global site tag (gtag.js) - Google Analytics