equals() hashCode()的比较

equals() hashCode()

equals()

equals()默认比较引用地址,重写equals()可实现判断对象内同是否相等,一般用于集合元素的比较,避免重复插入。

equals() 必须满足的条件

equals()方法要求我们必须满足以下条件:

  • 自反性(Reflexive):对于非null的x来说,x.equals(x)必须返回true;
  • 对称性(Symmetric):对于非null的x和y来说,如果x.equals(y)为true,则y.equals(x)也必须为true;
  • 传递性(Transitive):对于非null的x、y和z来说,如果x.equals(y)为true,y.equals(z)也为true,那么x.equals(z)也必须为true;
  • 一致性(Consistent):对于非null的x和y来说,只要x和y状态不变,则x.equals(y)总是一致地返回true或者false;
  • 对null的比较:即x.equals(null)永远返回false。

hashCode()

哈希码:哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看哈希码的算法实现。

hashCode()的常用实现

根据对象的值计算其物理存储位置,即hash值,两个equals相等的对象,其hashCode一定相等,但是即使值不相等,也可能得到相同的hash值,因为在同一hash值的位置形成了链表,可以看出,每次new出一个对象,直接计算出其hash值,然后寻找对应位置上,再使用equals方法比较,是否已存在值就可以知道对象是否重复了,这样比依次调用equals()与集合中的每个元素比较要节省很多时间。hash地址允许冲突,但是设计的越分散性能越好。

  • Object类的hashCode():返回对象所在的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
  • String类的hashCode():根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串所在的堆空间相同,返回的哈希码也相同。
  • Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100,由此可见,2个一样大小的Integer对象,返回的哈希码也一样。

equals()与hashCode()的结果比较

  • equals相等,hashcode一定相等
  • equals不等,hashcode不一定不等
  • hashcode相等,equals不一定相等
  • hashcode不等,equals一定不等

重写equls() hashCode()

建议使用ecplise自动生成。

二者必须同时重写:
假如只重写equals而不重写hashcode,那么Student类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故两者的hashcode不一定相等。

然而重写了equals,且s1.equals(s2)返回true,根据hashcode的规则,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals一定要重写hashcode,而且从Student类重写后的hashcode方法中可以看出,重写后返回的新的哈希值与Student的两个属性有关。

Demo

JavaBean

public class EqualsDemoClass {
	
	private String value;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((value == null) ? 0 : value.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		EqualsDemoClass other = (EqualsDemoClass) obj;
		if (value == null) {
			if (other.value != null)
				return false;
		} else if (!value.equals(other.value))
			return false;
		return true;
	}

	
}

Main

public class App 
{
    public static void main( String[] args )
    {
    	EqualsDemoClass a = new EqualsDemoClass();
    	a.setValue("1");
    	EqualsDemoClass b = new EqualsDemoClass();
    	b.setValue("1");
    	/**
    	 * 未重写,返回值为fale,因为比较的是二者的引用地址
    	 * 重写后,返回值为true,比较的是两个对象的值
    	 */
    	System.out.println(a.equals(b));
    	
    	/**
    	 * 未重写,返回值不同,因为是根据对象物理地址算出
    	 * 重写后,返回值相同,是根据对象的值算出
    	 */
    	System.out.println(a.hashCode());
    	System.out.println(b.hashCode());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值