Home >Java >javaTutorial >What are equals and == in Java? What are the differences?

What are equals and == in Java? What are the differences?

青灯夜游
青灯夜游forward
2018-10-19 17:12:183813browse

The content of this article is to introduce what equals and == are in Java? What are the differences? It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

1. Data types in java and the meaning of "==":

  • Basic data types (also called primitive data types): byte, short, char, int, long, float, double, boolean. To compare them, use the double equal sign (==), compares their values ​​.

  • Reference data type : When they are compared using (==), they are compared The storage address in memory (to be precise, Heap memoryaddress).

Note: For the second type, unless they are the same new object, the result of their comparison is true, otherwise the result of the comparison is false. Because every new time, the heap memory space will be re-opened.

2. Introduction to the equals() method:

All classes in JAVA inherit from the super class Object. In the Object class An equals method is defined in. The source code of equals is written like this:

public boolean equals(Object obj) {
    //this - s1
    //obj - s2
    return (this == obj);
}

As you can see, the initial default behavior of this method is to compare the memory address value of the object. Generally speaking, it is of little significance. Therefore, this method has been overridden in some class libraries, such as String, Integer, and Date. Among these classes, equals has its own implementation (generally used to compare whether the member variable values ​​of objects are the same), instead of comparing the storage address of the class in the heap memory.

So, For equals comparison between composite data types, without overriding the equals method, the comparison between them is still the address value of the storage location in the memory. The result is the same as the double equal sign (==); if it is overwritten, follow the requirements for overwriting.

Let’s summarize the above two paragraphs:

== Function:
Basic type: What is compared is whether the values ​​are the same
Reference type: What is compared is whether the address value is the same

The role of equals:
Reference type: by default , what is compared is the address value.

Note: However, we can override this method ourselves according to the situation. Generally, rewriting is automatically generated, and the member variable values ​​of the comparison objects are the same

3. The equals() method of the String class:

Now let's take the String class as an example:

We go to the \src\java\lang directory to find the String class, and find that the equals method has been rewritten as follows:

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

As can be seen from the above code, String The overridden equals() method in the class actually compares the contents of two strings. Let's take a look at the comparison of String classes through actual code.

1. The example code is as follows:

public class StringDemo {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        System.out.println(s1 == s2);   // true
    }
}

In the above code, use "==" to compare s1 and s2, and the returned result is true.

2. If you slightly change the program, you will find something strange:

public class StringDemo {
    public static void main(String args[]) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        String str3 = str2; // 引用传递
        System.out.println(str1 == str2); // false
        System.out.println(str1 == str3); // false
        System.out.println(str2 == str3); // true
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // true
        System.out.println(str2.equals(str3)); // true
    }
}

In the 4th line of code above, we create a new object, use "==" to compare s1 and s2, and return The result is false; and using "equals" to compare s1 and s2, the returned result is true.

In order to analyze the above code, we must first analyze the heap memory space and stack memory space. This is very important:

Please explain the difference between "==" and equals() in string comparison?

  • ==: The comparison is whether the values ​​​​of the two string memory addresses (heap memory) are equal, which is a numerical comparison;

  • equals(): Compares the contents of two strings, which is a content comparison.

#In the future, equals() will be used when making string equality judgments.

3. Change the program again:

public class ObjectDemo{
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = new String("Hello");
        s2 = s2.intern();
        System.out.println(s1 == s2);       //  true
        System.out.println(s1.equals(s2));  //  true
    }
}

In line 5 of the above code, the intern() method "abc".intern() of java.lang.String The return value of the method is still the string "abc". On the surface, it seems that this method is useless. But in fact, it does a small trick: Checks whether there is a string such as "abc" in the string pool. If it exists, it returns the string in the pool; if it does not exist, this method will "abc" is added to the string pool before its reference is returned.

4. Compare the values ​​of two objects:

The code is as follows:

package com.smyh;

public class ObjectDemo {
    public static void main(String args[]){
        Student student1 = new Student("生命壹号",22,"成都");
        Student student2 = new Student("生命壹号",22,"成都"); 
        System.out.println(student1==student2);
        System.out.println(student1.equals(student2));
    }
}
class Student {
    private String name;
    private int age;
    private String address;
    public Student(String name,int age,String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
    //重写Object类中的equals方法(比较两个对象的值是否相等)
    public boolean equals(Object obj){
        //为了提高效率:如果两个内存地址相等,那么一定是指向同一个对内存中的对象,就无需比较两个对象的属性值(自己跟自己比,没啥意义嘛)
        if(this==obj){
            return true;
        }
        
        //为了提供程序的健壮性
        //我先判断一下,obj是不是学生的一个对象,如果是,再做向下转型,如果不是,直接返回false。
        //这个时候,我们要判断的是对象是否是某个类的对象?
        //记住一个格式:对象名 instanceof 类名。表示:判断该对象是否是该类的一个对象       
        if(!(obj instanceof Student)){        
            return false;                
        }
        
        //如果是就继续
        Student s = (Student)obj;//强制转换,即向下转型(毕竟Object类型没有具体的对象属性)        
        return this.name.equals(s.name) && this.age == s.age && this.address.equals(s.address);//判断两个对象的属性值是否相等
    }
}

上述代码中,首先判断传递进来的对象与当前对象的地址是否相等,如果相等,则肯定是同一个堆内存中的对象。因为传递进来的参数是Object类型,所以任何对象都可以接收。一旦接收进来,就将Object类型的对象向下转型,然后判断具体的属性值。

 运行效果:

五、equals()的重写规则

前面我们已经知道如何去重写equals方法来实现我们自己的需求了,但是我们在重写equals方法时,还是需要注意如下几点规则的。

  • 自反性。对于任何非null的引用值x,x.equals(x)应返回true。

  • 对称性。对于任何非null的引用值x与y,当且仅当:y.equals(x)返回true时,x.equals(y)才返回true。

  • 传递性。对于任何非null的引用值x、y与z,如果y.equals(x)返回true,y.equals(z)返回true,那么x.equals(z)也应返回true。

  • 一致性。对于任何非null的引用值x与y,假设对象上equals比较中的信息没有被修改,则多次调用x.equals(y)始终返回true或者始终返回false。

  • 对于任何非空引用值x,x.equal(null)应返回false。

六、为什么重写equals()的同时还得重写hashCode()

我们知道equals()和hashCode()是java Object中两个基本方法,有时候由于业务的需求,需要我们重写equals()方法,比如对于Person类中,业务的需要让我们当Person对象的cardID一致的时候,就认为两个对象equals,此时就需要在Person类中重写equals()方法,如下:

public class Person
{

    public String name;
    public int age;
    public String cardID;

    .....// 省略

    @Override
    public boolean equals(Object o)
    {
        if (o instanceof Person)
        {
            Person p = (Person) o;
            return this.cardID.equals(p.cardID);
        } else
        {
            return false;
        }
    }

    @Override
    public int hashCode()
    {
        return this.cardID.hashCode();
    }

    ......// 省略


}

保证相同对象的hashCode一定相同,不同对象的hashCode基本相同。

阅读HashMap的源码,我们可以看到,HashMap中实现了一个Entry[]数组,数组的每个item是一个单项链表的结构,当我们put(key, value)的时候,HashMap首先会newItem.key.hashCode()作为该newItem在Entry[]中存储的下标,要是对应的下标的位置上没有任何item,则直接存储上去,要是已经有oldItem存储在了上面,那就会判断oldItem.key.equals(newItem.key),那么要是我们把上面的Person作为key进行存储的时候,重写了equals()方法,但没重写hashCode()方法,当我们去put()的时候,首先会通过hashCode() 计算下标,由于没有重写hashCode(),那么实质是完整的Object的hashCode(),会受到Object多个属性的影响,本来equals的两个Person对象,反而得到了两个不同的下标。

同样的,HashMap在get(key)的过程中,也是首先调用hashCode()计算item的下标,然后在对应下标的地方找,要是为null,就返回null,要是 != null,会去调用equals()方法,比较key是否一致,只有当key一致的时候,才会返回value,要是我们没有重写hashCode()方法,本来有的item,反而会找不到,返回null结果。

所以,要是你重写了equals()方法,而你的对象可能会放入到散列(HashMap,HashTable或HashSet等)中,那么还必须重写hashCode(), 如果你的对象有可能放到有序队列(实现了Comparable)中,那么还需要重写compareTo()的方法。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。更多相关教程请访问Java视频教程java开发图文教程bootstrap视频教程

The above is the detailed content of What are equals and == in Java? What are the differences?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete