Java中的hashcode方法

参考与学习:http://www.cnblogs.com/skywang12345/p/3324958.html
http://www.cnblogs.com/dolphin0520/p/3681042.html

旨在通过这篇文章把现在我明白的;未来我可能忘记的以及混淆的,写清楚。

hashCode方法
该方法定义在Object类中,是native方法;
(哦我去)

其他啰嗦的我不想写了;不懂直接去看上面两篇博客;(果然!)
点一:equals与==的关系和区别:

Object类中定义的equals方法,就是使用了==来进行比较的;
==,比较的是对象的内存地址是否相同;(这个记住了啊)

点二:我的疑问点在于:
为什么重写equals方法,一定要重写hashCode方法;
第一篇文章解答了我的疑惑;
当定义的类,比如说不会创建Student类对应的散列表中,例如,没有HashMap<\Student>结构,其实在重写equals方法时,是不需要重写hashcode方法的。

public class Student {
	String name;
	int age;
	
	public Student(){}
	
	public Student(String name,int age){
		this.name=name;
		this.age=age;
	}
	
	@Override
	public boolean equals(Object obj){
		if(obj==null) return false;
		if(this==obj) return true;
		if(this.getClass()!=obj.getClass()) return false;
		Student st=(Student)obj;
		return this.name==st.name&&this.age==st.age;
	}
	
	public static void main(String[] args){
		Student s1=new Student("lee",18);
		Student s2=new Student("lee",18);
		System.out.println(s1.equals(s2));
	}
}

这个时候比较这两个对象是否相等,只需要重写了equals方法就可以了。(另外注意一下equals方法怎么重写的)

但如果创建了类对应的散列表,如HashMap<\Student>,则在重写equals方法的同时,要重写hashcode方法;

public class Student {
	String name;
	int age;

	public Student() {
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if (this == obj)
			return true;
		if (this.getClass() != obj.getClass())
			return false;
		Student st = (Student) obj;
		return this.name == st.name && this.age == st.age;
	}
	
	@Override
	public String toString(){
		return "name:"+this.name+" age:"+this.age;
	}

	public static void main(String[] args) {
		Set<Student> set = new HashSet<Student>();
		Student s1 = new Student("lee", 18);
		Student s2 = new Student("lee", 18);
		set.add(s1);
		set.add(s2);
		System.out.println(s1.equals(s2));
		Iterator it=set.iterator();
		while(it.hasNext()){
			Student st=(Student)it.next();
			System.out.println(st.toString());
		}
	}
}

运行结果:

true
name:lee age:18
name:lee age:18

发现,经equals比较,两个对象相等;但不允许元素重复的set中却包含了这两个对象。造成这个问题的原因就是因为没有重写hashcode方法;
散列表在存储元素的时候,首先根据对象的hashcode方法获得散列值(基于对象的内存地址);这两个对象明显有不同的内存空间,所以通过hashcode获得的散列值不同;HashSet就会认为这是两个不同的对象,分别存储。
解决:

public class Student {
	String name;
	int age;

	public Student() {
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if (this == obj)
			return true;
		if (this.getClass() != obj.getClass())
			return false;
		Student st = (Student) obj;
		return this.name == st.name && this.age == st.age;
	}
	
	@Override
	public String toString(){
		return "name:"+this.name+" age:"+this.age;
	}
	
	@Override
	public int hashCode(){
		return name.toUpperCase().hashCode()^age;
	}

	public static void main(String[] args) {
		Set<Student> set = new HashSet<Student>();
		Student s1 = new Student("lee", 18);
		Student s2 = new Student("lee", 18);
		set.add(s1);
		set.add(s2);
		System.out.println(s1.equals(s2));
		Iterator it=set.iterator();
		while(it.hasNext()){
			Student st=(Student)it.next();
			System.out.println(st.toString());
		}
	}
}

运行结果:

true
name:lee age:18
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值