java equals与hashCode

    如果只看jdk文档对于新手来说,很难理解java为什么要求重写这两个方法。在面向对象的世界里,如何确定两个对象是否相等(或者说逻辑上相等)是要解决的一个问题,Java通过equal方法来确定两个对象是否相等。Java对象的创建是在堆上进行的,如果用new关键字创建一个类的两个对象,java里时如何判定这两个对象是否相等的呢?

 

举个例子:

class Employee {
	Integer id;
	public void setId(Integer id) {
		this.id = id;
	}
} 

 假如一家公司认为只要员工编号相同就是同一个员工(虽然有点不太合理,但没想到更像样的例子)。接下来,如下代码来判断员工是否是同一个人

        Employee e1 = new Employee();
        Employee e2 = new Employee();
        e1.setId(1);
        e2.setId(1);
        
        System.out.println(e1.equals(e2));

 很遗憾,这段代码的输出为false。

为了达到判定这样的两个员工是同一个员工,需要重写equals方法。

class Employee {
	Integer id;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Override
	public boolean equals(Object o) {
		if(o == null) {
			return false;
		}
		if (o == this) {
			return true;
		}
		if (getClass() != o.getClass()) {
			return false;
		}
		Employee e = (Employee) o;
		return (this.getId() == e.getId());
	}
}

 

运行如下的测试方法

        Employee e1 = new Employee();
        Employee e2 = new Employee();
        e1.setId(1);
        e2.setId(1);
        
        System.out.println(e1.equals(e2));
         
        Set<Employee> employees = new HashSet<Employee>();
        employees.add(e1);
        employees.add(e2);
        
        System.out.println(employees);
        System.out.println(e1.equals(e2));

 程序运行结果如下:

true

[com.shunwang.meteor.example.Employee@dc8569, com.shunwang.meteor.example.Employee@1bab50a]

 

第一个运行结果是正确了,但第二个竟然输出了两个,Java中Set是能去重的,那问题出在哪里呢?

原来,Java中对于HashSet的存储利用了HashMap,而HashMap是采用数组加链表的数据结构的(如果不清楚请读一下HashMap的源代码,如果了解HashMap的存储结构,此问题就很好理解了)。HashMap首先通过对象的hashcode计算存储位置(如果hash冲突,该位置用一个链表解决冲突),再比较元素的值。上述问题早于未重写对象的hashcode方法(默认继承Object,默认返回对象的内存地址编号)。修改代码如下:

class Employee {
	Integer id;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Override
	public boolean equals(Object o) {
		if(o == null) {
			return false;
		}
		if (o == this) {
			return true;
		}
		if (getClass() != o.getClass()) {
			return false;
		}
		Employee e = (Employee) o;
		return (this.getId() == e.getId());
	}
	
	@Override
	public int hashCode() {
	    final int code = 31;
	    int result = 1;
	    result = code * result + getId();
	    return result;
	}
}

 

执行结果:

true

[com.shunwang.meteor.example.Employee@20]

 

如果理解这两个方法的用处,那些描述文章中描述的各种"性"就好理解了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值