String类的equals()的作用和源代码解读

1.  了解equals()方法

equals方法是用于比较两个对象是否相等的方法,定义在Object类中。其默认实现仅比较对象的引用地址,但可以通过重写方法实现对对象内容的比较。只有引用数据类型才可以使用equals方法,我们点进equals方法的源码:

我们看代码前几行,观察到当传入进来的参数之间互相比较时,是在使用“ == ”来比较两者间引用地址的相等关系。这里回顾一下 == equals 的区别

2.   == 运算符

在基本数据类型中, == 用于比较两者之间的值

在引用数据类型中, == 用于比较两者的内存地址

3.  equals() 方法

只有引用数据类型才可以使用equals()方法,如果没有重写equals()方法,会默认调用Object类中的equals()方法。其仍然使用 == 来进行内存地址的比较。不过在String类中已经重写了equals方法,所以我们可以直接使用equals方法来比较字符串内容。

3.1  String类重写的equals方法解读:

public boolean equals(Object anObject) {
        // 先比较两者内存地址,如果相同直接返回true
        if (this == anObject) {
            return true;
        }
        //检查传入参数的类型
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;        //将当前字符串长度赋给n
            //检查当前字符串的长度
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                //将两个字符串进行逐字符比较
                while (n-- != 0) {
                    if (v1[i] != v2[i])   //有一个字符不匹配则返回false
                        return false;
                    i++;
                }
                return true;              //每个字符都匹配,返回true
            }
        }
        //传入参数类型错误,返回false
        return false;
    }

4.  举例验证:

4.1  在String类中分别使用 == 和equals方法进行字符串比较:

public class Demo1 {
    public static void main(String[] args) {
        String str1 = new String("2022");
        String str2 = new String("2022");

        System.out.println(str1 == str2);
        System.out.println(str1.equals(str2));
    }
}

我们创建两个String类对象,分别使用==equals来比较两个相同内容的字符串,观察输出结果:

结果分析:

==运算符的比较输出结果为false,在前文中说过其比较的是内存地址,又因为我们创建了两个String类的对象,自然其内存地址也是不同的。所以输出为false

equals方法输出结果为true,这是因为String类中重写了equals方法,对两个字符串进行逐字符比较,字符内容相同,所以返回true

上述equals方法能比较字符串内容的前提是使用String类中的equals方法,如果在自定义类中,则需要手动重写equals方法,否则仍然是进行 == 运算比较内存地址。

4.2  在自定义类中分别使用 == 和equals方法进行字符串比较:

public class Demo1 {
    public static void main(String[] args) {
        myArray arr1 = new myArray("2022");
        myArray arr2 = new myArray("2022");
        System.out.println(arr1.equals(arr2));
    }
}

class myArray {
    private String value;

    public myArray(String value) {
        this.value = value;
    }
}

自定义myArray类,在主函数中创建myArray对象,仍然使用equals方法进行比较,观察运行结果

可以看到结果为false,这是因为自定义类中没有事先重写好的equals方法, 所以其本质上是使用 == 在进行对象间的内存地址比较。

自定义类中重写equals方法:

class myArray {
    private String value;

    public myArray(String value) {
        this.value = value;
    }

    @Override
    public boolean equals(Object obj){
        //如果obj和当前字符串地址一样,返回true
        if (this == obj){
            return true;
        }
        //判断传入参数是否为空或类型是否不同
        if (obj == null || getClass() != obj.getClass()){
            return false;
        }
        //强制类型转换后比较value的值
        myArray array = (myArray) obj;
        return value == array.value;
    }
}

重写equals方法,逐个比较value的属性值,达到比较字符串之间内容的目的,这样在使用自定义类myArray时使用equals方法时,则会执行在类中被重写过的方法。

验证: 

package Demo3;

public class Demo1 {
    public static void main(String[] args) {
        myArray arr1 = new myArray("2022");
        myArray arr2 = new myArray("2022");
        myArray arr3 = new myArray("8888");
        System.out.println(arr1.equals(arr2));
        System.out.println(arr1.equals(arr3));
    }
}

class myArray {
    private String value;

    public myArray(String value) {
        this.value = value;
    }

    @Override
    public boolean equals(Object obj){
        if (this == obj){
            return true;
        }
        if (obj == null || getClass() != obj.getClass()){
            return false;
        }
        myArray array = (myArray) obj;
        return value == array.value;
    }
}

重写equals方法后,添加新的myArray对象arr3,字符串内容为“8888”。分别比较arr1arr2arr1arr3

 arr1arr2比较运行结果为true,说明两者字符串内容一致。arr1arr3比较结果为false,说明两者字符串内容不一致。

5.  总结:

        使用String类的equals方法在比较两个字符串时,首先会检查两个对象的引用是否相同,如果相同,接着检查传入的对象是否是String类型,如果符合条件,则继续比较字符串的长度。如果长度不同,直接返回false,如果长度相同,则逐个字符比较两个字符串的内容。如果内容完全相同,返回true,否则返回false。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值