equals and = = Application and difference (in-depth understanding of source code)

equals and = = Application and difference (in-depth understanding of source code)

Double equal sign (= =)

Two cases of double equal sign comparison

For the = = sign, only two cases need to be considered:

  1. The basic data type uses = =, comparing values
  2. The reference data type is = =, which compares the (heap) memory address of the object stored in the variable (stack) memory to judge whether the addresses of two objects are the same, that is, whether they refer to the same object. The comparison is the real pointer operation.

Source code and example analysis

Comparison between Integer and Integer,Integer and int

    Integer a1=new Integer(4321);
    Integer a2=new Integer(4321);
    int a3=4321;
    System.out.println("a1==a2:"+(a1==a2));//The result is false because A1 and A2 are two different objects, and the address values in their heap are naturally different
    System.out.println("a1==a3:"+(a1==a3));//The result is true because Java's automatic unpacking mechanism compares two values
    System.out.println("a3==a1:"+(a3==a1));//The result is false for the same reason as above
    Integer a4=4321;
    Integer a5=4321;
    /**
     * Integer a4=4321;
     * Integer a5=4321;
     * It's equivalent to execution
     * Integer a4=Integer.valueOf (4321) ;
     * Integer a5=Integer.valueOf (4321) ;
     */
    System.out.println("a4==a5:"+(a5==a4));//The result is false, which is equivalent to creating two objects with naturally different addresses
    
    Integer a6=100;
    Integer a7=100;
    /**
     * Why is this different
     * According to the source code of packing operation
     * public static Integer valueOf(int i) {
     *         if (i >= -128 && i <= 127)
     *             return IntegerCache.cache[i + 127];
     *             //If the value of i is greater than - 128 and less than 127, an Integer object that already exists in a buffer is returned
     *         return new Integer(i);
     *         //Otherwise, new is returned as an Integer object
     * }
     * It can be seen that if it is between - 128-127, the same object is boxed (to save memory)
     *Therefore, if the packing operation is between - 128 and 127, the same objects will be loaded!
     */
    System.out.println("a6==a7:"+(a6==a7));//Is true
    Integer a8=128;
    Integer a9=128;
    System.out.println("a8==a9:"+(a8==a9));//Is false
    Integer a10=-128;
    Integer a11=-128;
    System.out.println("a10==a11:"+(a10==a11));//Is true
    a10=127;
    a11=127;
    System.out.println("a10==a11:"+(a10==a11));//Is true
    /**
     * Note that this method generates objects directly!
     * The address value is not obtained by boxing, but the generated address is directly created in the heap!
     * All different
     */
    Integer aa1=new Integer(1);
    Integer aa2=new Integer(1);
    System.out.println("aa1==aa2:"+(aa1==aa2));//Is false

Types of Java automatic boxing and unpacking mechanism

Parsing of = = in String

    String s1="12345";
    String s2="12345";
    String s3=new String("12345");
    String s4=new String("12345");
    /**
     * String s1=="xxx"This string creation method is not created in the heap
     * To save space, a constant pool is created at runtime, that is, in the method area
     * s1 And s2 point to the same address
     */
    System.out.println("s1==s2:"+(s1==s2));//true
    System.out.println("s1==s3:"+(s1==s3));//false, s1 points to the address of the constant pool, and s3 points to the address in the heap
    System.out.println("s3==s4:"+(s3==s4));//False. s3 and s4 point to different addresses in the heap, so false

equals

Usage overview

equals has not been rewritten. It is the comparison address, which is equivalent to===

reason:
Equals is used to compare whether the contents of two objects are equal. Since all classes inherit from the java.lang.Object class, it is applicable to all objects. If this method is not overridden, the method in the Object class is still called, while the equals method in the Object returns the judgment of = =.

equals source code
Obviously, the java source code has made special treatment for the String class. The equals of String is not to compare the address value, but to compare the content of String.

  1. First of all, if two objects are in the heap, the address values cannot be equal. Therefore, when comparing the contents of two objects instead of addresses, it is necessary to rewrite the equals method to compare the contents
  2. By default, hashcode indicates the storage address of the object. If the two things are the same, they should be the same as the key of HashMap. Therefore, since the equal rules have changed, it is natural to rewrite the hashcode method to follow the changes!

equals of HashSet

HashSet itself overrides equals!

    HashSet<Integer> set1=new HashSet();
    HashSet<Integer> set2=new HashSet();
    set1.add(1);
    set1.add(2);
    set2.add(1);
    set2.add(2);
    System.out.println(set1.equals(set2));//Return true!

And what's more meaningful is
The underlying implementation of HashSet is implemented through HashMap

equals of array

The equals of Array is native

    Integer[] array1={1,2,3};
    Integer[] array2={1,2,3};
    System.out.println(array1.equals(array2));//false
    
    //java.util.Arrays provides us with hashCode and euqals
    System.out.println(Arrays.equals(array1,array2));//true

However, java.util.Arrays provides us with hashCode and euqals, which compare the internal elements in the array.


ps inspiration:
We can also learn this way
You can write a general class without overriding the method, in which the method calculates hashcode and equals!

Why rewrite the equals() method in JAVA? Why rewrite the hashcode() method

Why overload the hashCode method?
Answer: generally, you don't need to overload hashCode. You can overload hashCode only when the class needs to be placed in the collection of HashTable, HashMap, HashSet and other hash structures. So why overload hashCode? For example, HashMap is a large memory block with many small memory blocks. There are a series of objects in the small memory block. You can use hashCode to find the small memory block hashCode% size (the number of small memory blocks). Therefore, when equal is equal, hashCode must be equal, and if it is an object object object, hashCode and equal methods must be overloaded.

For example, we have object A and object B. now we rewrite the equals method to make them equal. Then we use the hash HashSet to store object A, and then use set.contains(B). We can't find the existence of B!

Object overrides equlas and hashcode instances

package com.company;

public class Main {
    public static void main(String[] args) {
	// write your code here
        Person p1=new Person("l1",11,"male");
        Person p2=new Person("l1",11,"male");
        Person p3=new Person("l1",12,"male");
        System.out.println(p1==p2);//false
        System.out.println(p1.equals(p2));//true
        System.out.println(p1.equals(p3));//false
    }
}


class Person{
    String name;
    Integer age;
    String sex;
    @Override
    public int hashCode() {
        return 31*(this.name.hashCode()+31*this.age.hashCode()+31*(this.sex.hashCode()));
    }

    @Override
    public String toString() {
        return this.name+"  "+this.age+"  "+this.sex;
    }

    @Override
    public boolean equals(Object obj) {
        Person person1=(Person) obj;
        return this.hashCode()==person1.hashCode();
    }

    public Person() {
    }

    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

outPut

false
true
false
Process finished with exit code 0

Ps: if you want to use the equal method, use object < < impossible to be empty >. Equal (object < < possible to be empty >)
"target".equals(foo)

Keywords: Java jvm Code Style

Added by rReLmy on Tue, 23 Nov 2021 23:21:24 +0200