面试常问:equals()与 == 区别

本文讨论了Java中`equals()`和`==`的区别,特别是在String类型比较时的重要性。重点讲解了基本类型和引用类型比较的原理,以及如何使用`intern()`方法确保字符串内存效率。
摘要由CSDN通过智能技术生成

面了很多家公司,总有几家公司一开口就问“你知道equals()与  == 有啥区别吗”,所以在此写文章记录下来。

学生时代刚学java的时候,常因为String类型的比较使用的是==导致oj无法通过,最后发现要用equals,简直想给自己一巴掌。String类型值比较一定要用equals啊!!

结论

==:

1.基本类型(boolean,byte,short,char,int,float,long,double,)的比较就是值是否相同

2.引用类型的比较就是地址值是否相同

equals:

默认情况下比较的是地址,但很多数类都对它进行了重写可以进行值的比较。

来源

==是运算符,equals是Object类中定义的一个方法

例子

==与equals的简单使用比较

public class equalsORequals {
    public static void main(String args[]){
        int a = 1;
        int b = 1;
        String str1 = new String("abc");
        String str2 = new String("abc");
        System.out.println("a==b is "+(a==b));
        //int不能使用equals
//        System.out.println("a.equals(a) is " a.equals(b));
        System.out.println("str1==str2 is " +(str1 == str2));
        System.out.println("str1.equals(str2) is " +(str1.equals(str2)));
    }
}

我们可以看一下String中equals的源码,它是对取出的String进行字符的一一比较。

/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(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;
    }

深入了解String中使用==

这里给出一个经典的例题代码

class StringEqualTest {
    public static void main(String[] args) {
        String s1 = "StringTest";
        String s2 = new String("StringTest");
        String s3 = "String";
        String s4 = "Test";
        String s5 = "String" + "Test";
        String s6 = s3 + s4;
        System.out.println(s1 == s2);  //false
        System.out.println(s1 == s5);   //true
        System.out.println(s1 == s6);   //false
        System.out.println(s1 == s6.intern()); //true
        System.out.println(s2 == s2.intern()); //false
    }
}

首先我们要明白如果单独使用String s2 = new String("StringTest");这个过程创建了两个对象,首先是new一个对象代表的s2存在堆区中,然后在常量池中创建了一个字面量是"test"。

在本例子中s1已经创建常量池对象,那么s2创建过程中就不会再在常量池中创建。

1.s1==s2(false),==比较的是内存地址,而s2是new出来的新对象在堆中(该新对象也是指向常量池中的“StringTest”的),s1指向的是常量池中的“StringTest”。一个在堆中,一个在常量池肯定不一样。

2.s1==s5(true),字符串+的本质是创建了StringBulider对象进行append操作,然后将拼接后的StringBulider对象用toString进行处理,处理后生成的字符串放在字符串池中找有没有相同值的字符串,如果有将引用(s5)直接连接到已有的字符串地址,所以s1和s5的地址相同

3.s1 == s6(false),因为s6是通过运行时拼接生成的新对象,存储在堆内存中,而s1指向常量池中的对象。请重新解释一下我不太懂

4.s1 == s6.intern() (true),因为s6.intern()会返回字符串在常量池中的引用,所以与s1指向的对象相同。

5.s2 == s2.intern() (false),因为new String("StringTest")会在堆中创建一个新的字符串对象,而intern()方法会检查常量池中是否存在相同值的字符串,如果存在则返回常量池中的引用,否则将其加入常量池并返回引用,但在这里常量池中已经存在了一个相同值的字符串对象,所以不会返回s2所指向的堆中的对象。

intern()

在Java中,intern() 方法是 String 类的一个方法,它的作用是:

  1. 如果常量池中已经存在该字符串(与调用 intern() 的字符串内容相同),则返回常量池中该字符串的引用。
  2. 如果常量池中不存在该字符串,则将该字符串添加到常量池中,并返回常量池中该字符串的引用。

使用 intern() 方法可以确保相同内容的字符串在内存中只存在一份,从而节省内存空间,并且可以用于比较字符串的引用是否相同。

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值