Java基础 ==和equals的区别

一、"=="和equals的区别

1、首先,equal和最根本的区别在于equal是一个方法,而"==“是一个运算符。
2、一般来说,运算符比较的是在内存中的物理地址,.equal()比较的是哈希算法值是否相等(即hashcode),且基本数据类型只能用”==“来进行比较。如果比较的双方没有哈希值,那么此时”==“和equal()比较的都是物理地址,可以互相替换(事实上在object类中equal()方法就是用”=="实现的,只是在有的需要比较哈希值的类中equal()方法被重写了)。
3、equal()可以重写,在set集合中,jvm就是根据hashcode(),和equal()这两个方法来判断元素是否重复,如果要重写,建议两个方法一起重写,否则可能会出现安全性问题。

二、equals与==的区别从以下几个方面来说

1、equals不能运用与基本类型的比较,基本类型比较只能有“==”;

public class Test {
    public static void main(String[] args){
        int a = 3;
        int b = 4;
        int c = 3;
        System.out.println(a == b);//结果是false 
        System.out.println(a == c);//结果是true 
        System.out.println(a.equals(c));//错误,编译不能通过 
    }
}

2、对于基本类型的包装类型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的

public class Test {
    public static void main(String[] args) { 
        Integer n1 = new Integer(30);
        Integer n2 = new Integer(30);
        Integer n3 = new Integer(31);
        System.out.println(n1 == n2);//结果是false 两个不同的Integer对象,故其地址不同, 
        System.out.println(n1 == n3);//那么不管是new Integer(30)还是new Integer(31) 结果都显示false 
        System.out.println(n1.equals(n2));//结果是true 根据jdk文档中的说明,n1与n2指向的对象中的内容是相等的,都是30,故equals比较后结果是true 
        System.out.println(n1.equals(n3));//结果是false 因对象内容不一样,一个是30一个是31 
    }
}

3、对于String(字符串)、StringBuffer(线程安全的可变字符序列)、StringBuilder(可变字符序列)这三个类作进一步的说明

public class Test {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        String s4 = new String("abc");
        StringBuffer s5 = new StringBuffer("abc");
        StringBuffer s6 = new StringBuffer("abc");
        System.out.println(s1 == s2);//(1)true 
        System.out.println(s1.equals(s2));//(2)true 
        System.out.println(s3 == s4);//(3)flase 
        System.out.println(s3.equals(s4));//(4)true
        System.out.println(s1 == s3);//(5)false
        System.out.println(s1.equals(s4));//(6)true 
        System.out.println(s1.equals(s5));//(7)false 
        System.out.println(s1.equals(s6));//(8)false 
        System.out.println(s5.equals(s6));//(9)false 
    }
}

解释一下:
1、s1与s2分别指向由字符串常量”abc” 创建的对象,在常量池中,只有一个对象,内容为abc,有两个引用s1和s2指向这个对象,故这两个引用变量所指向的地址是相同的,因而(1)处的运行结果为true
2、因为s1.equals(s2)是比较s1和s2所指向的对象的内容是否相等,而我们知道这两个对象的内容都是字符串常量”abc”,故标记(2)处的运行结果是true。
3、s3和s4,这两个引用变量所指向的对象的内容都是一样的(内容都是abc),但是这两个对象是用new操作符创建处类的,是在内存中分配两块空间给这两个对象的,因而这两个对象的内存地址不一样,故事两个不同的对象,标记(3)处的s3 == s4 运行结果为false,但是内容一样,故标记(4)处的s3.equals(s4)运行结果为true
4、s1和s3分别指向两个不同的对象(之所以这样称呼,是因为这两个对象在内存中的地址不相同,故而对象不相同),故标记为(5)处的s1 == s3运行结果为false,但是内容一样,故标记(6)处的s1.equals(s3)运行结果为true
5、其中(7)、(8)、(9)处都为false,StringBuffer类和StringBuilder类中没有重新定义equals这个方法,因此这个方法就来自Object类, 而Object类中的equals方法是用来比较“地址”的等同于“==”,所以等于false.

三、总结一下

equals:
1、对于object类(或继承object类,但无实现自定义equal),是比较对象的类型的,除非同一对象,都不相等。
2、对于基本类型(如int)不能使用equal。
3、对于基本类型的封装类,equal是比较其类型。
4、对于继承object类的,又实现了自定义equals(重写其equals),则是按自定义的equals执行,一般重写的就是重写成对其内容进行比较。一般api中继承object的类都已重写equals对内容进行比较。

== :
1、“==”比较两个变量本身的值,即两个对象在内存中的首地址。

你可能感兴趣的:(JAVA基础)