java基础提升3 -- hashCode与equals

一、 Object中的源码

1. Object中的equals方法
	1. Object中的 equals()方法:观察可知比较的是 toString()的返回值
    public boolean equals(Object obj) {
        return (this == obj);
    }
    
	2. Object中的 toString()方法:观察可知左边会获取含包名的类名,右边获取hashCode值并把
			hasCode转换为十六进制。
			   所以,equals比较两个类是否相同,主要还是比较他们是否是同一个类,以及他们的
			hashCode值是否相同
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

2. Object中的hashCode()方法

https://www.cnblogs.com/dolphin0520/p/3681042.html (参考文章)
https://blog.csdn.net/xusiwei1236/article/details/45152201 (参考文章)
https://blog.csdn.net/fenglibing/article/details/8905007 (hashCode的作用)
注意:hashCode()的注释指出了Object.hashCode()在JRE(Java Runtime Library)中应该遵循的一些契约(contract)
(PS:即使我们看不到源码,但是它的生成规则一定会遵守下面这个3个契约)

  1. 一致性(consistent),在程序的一次执行过程中,对同一个对象必须一致地返回同一个整数。

  2. 如果两个对象通过equals(Object)比较,结果相等,那么对这两个对象分别调用hashCode方法应该产生相同的整数结果。(PS:这里equalshashCode说的都是Object类的)

  3. 如果两个对象通过java.lang.Object.equals(java.lang.Ojbect)比较,结果不相等,不必保证对这两个对象分别调用hashCode也返回两个不相同的整数。

  Object中的 hashCode()方法:观察可知它是由原生函数而生成的,并且它的值是根据对象中的值生成的
		native :使用native关键字修饰的函数(方法),说明这个方法是原生函数,也就是这个方法
				是用C/C++语言实现的,并且被编译成了DLL,由java去调用。
				
	 public native int hashCode();

3. 总结(Object中)
  1. equals主要比较的就是两个对象的值是否相等,它的比较规则是“类全名 + @ + hasCode值”
  2. 从源码可知,为什么equals()比较相等的两个数,hasCode一定相等;equals()比较两个数不相等,hasCode不一定相等
  3. hashCode返回的并不一定是对象的(虚拟)内存地址,具体取决于运行时库和JVM的具体实现
  4. System.identityHashCode(obj)这个方法是根据内存地址获取的hash值,每次运行程序时,内存会为对象重新分配内存地址,因此得到的hash值也不一样。




二、 String中的源码

1. String中的hashCode方法
	1. String中的 hashCode()方法:首先把String中的变量hash赋值给要返回的变量h,再判断赋
					值之后是否为空,为空则计算hash值。并返回计算好的hash值。
	public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }


2. String中的equals()方法
 1. String中的 equals()方法:1. 首先比较传入对象和当前对象的内容是否相等(this直接使用
						调用的是toString方法,toString会直接返回字符串内容),比较字符串
						内容相等则直接返回true2.不相等则判断是否为相同类型,再判断字符串长度是否相等, 最后
		  				通过while循环比较两个字符串内容是否相等
			

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }


3. 总结(String中)
  1. Object中的两个方法都进行了重写,且重写后的hashCodeequals没有了关联。
  2. 重写后的equals主要是比较两个字符串的内容是否相等Object中的是主要是比较 是否是同一个类 + hashCode是否相等




三、 重写hashCode与equals

1. equals方法
    1. 自己重写的equals方法:1. 先判断传入对象与当前对象toString值是否相同


    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        OrgActivityAssistLike other = (OrgActivityAssistLike) that;
        return (this.getLikeId() == null ? other.getLikeId() == null : this.getLikeId().equals(other.getLikeId()))
            && (this.getActivityId() == null ? other.getActivityId() == null : this.getActivityId().equals(other.getActivityId()))
            && (this.getOrderId() == null ? other.getOrderId() == null : this.getOrderId().equals(other.getOrderId()))
            && (this.getCustomerId() == null ? other.getCustomerId() == null : this.getCustomerId().equals(other.getCustomerId()))
            && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
            && (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()));
    }

	2. 重写的toString方法
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", assistOrderId=").append(assistOrderId);
        sb.append(", helpOrderMoney=").append(helpOrderMoney);
        sb.append(", activityId=").append(activityId);
        sb.append(", orderId=").append(orderId);
        sb.append(", customerId=").append(customerId);
        sb.append(", createTime=").append(createTime);
        sb.append(", updateTime=").append(updateTime);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }


2. hashCode()方法
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getLikeId() == null) ? 0 : getLikeId().hashCode());
        result = prime * result + ((getActivityId() == null) ? 0 : getActivityId().hashCode());
        result = prime * result + ((getOrderId() == null) ? 0 : getOrderId().hashCode());
        result = prime * result + ((getCustomerId() == null) ? 0 : getCustomerId().hashCode());
        result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
        result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值