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:
- The basic data type uses = =, comparing values
- 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.
- 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
- 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)