java 中== equals hashcode源码剖析

本文详细解析了Java中==操作符与equals方法的区别,包括它们在字符串比较中的行为差异,以及hashcode方法的作用和重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

1.==

java中的==操作,比较的是两个对象的内存地址。如果两个对象的内存地址一致,则返回true。否则返回false。看一个简单的测试代码:

public static void test() {
	String s1 = "abc";
	String s2 = "abc";
	String s3 = "a" + "bc";
	String s4 = new String("abc");
	System.out.println(s1 == s2); //返回true
	System.out.println(s1 == s3); //返回true
	System.out.println(s1 == s4); //返回false
	}

首先明确一点,jvm的字符串常量存在于常量池(constant pool)中。而常量池是指编译期间就被确定,并且存在已编译的.class文件中的一些数据。包括了类,接口,方法等里面的常量,自然也包括字符串常量。

s1,s2指向的都是字符串常量,在内存中的地址一致,所以相等;“a”,"bc"分别都是字符串常量,相加以后的结果自然也是字符串常量,也在常量池里,所以s1==s3;而s4是new出来的一个字符串对象,内存地址中位于堆区,所以s1!=s4。

2.equals

equals()方法在object类里就有实现。object类,大家懂的,java里的祖宗类。

    public boolean equals(Object obj) {
        return (this == obj);
    }

祖宗类里的equals()方法实现相当简单粗暴,直接对两个对象做"=="比较。很显然,这要求是相当苛刻的。
在其他类中,一般都会重写equals方法。比如以String类为例:

   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;
    }

首先比较两个字符串是不是具有相同的内存地址。如果是,自然就是equlas了;如果不是,然后遍历String对象里的value[]字符数组。如果字符数组里每个字符都相等,那么这两个字符串也是equlas。如果有一个字符不相等,则为否。

3.hashcode

hashcode也是object祖宗类里的方法,而且这是个native方法:

public native int hashCode();

默认情况下,Object中的hashCode() 返回对象的32位jvm内存地址。如果对象不重写hashcode方法,则返回相应对象的32为JVM内存地址。

看看String类里重写的hashcode方法:

    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;
    }

h为string对象的初始hashcode值,默认为0。
由上面的代码很容易看出String类的hashcode计算方式为:
s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]

Hashcode在基于key-value的集合如:HashMap、LinkedHashMap中扮演很重要的角色。此外在HashSet集合中也会运用到,使用合适的hashcode方法在检索操作时的时间复杂度最好的是 O(1).关于hashcode的计算方法,完全可以写特别复杂的paper了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值