HashCode, Equals and ==

1. Operator ==

Data types in Java are divided into two categories: basic data types (byte, short, char, int, long, float, double, boolean) and reference data types (classes, interfaces, and arrays).

  • Basic data types
    In basic data types, the == operation compares whether the values of two variables are equal.
  • Reference data types
    In reference data types, the == operation compares the reference addresses of two objects in memory . Reference types store object references (addresses) in the stack, and objects are stored in the heap.

2. Equals method

equals is a method provided by the Object class by default.

  • No coverage is
    mainly used to determine whether the memory address of the object is the same address (is it the same object)
// Object 类equals 源码
public boolean equals(Object obj) {
    
    
    return (this == obj);
    }
  • Coverage situation
    If the equals method is covered, the function of the equals method is determined according to the specific code. Generally , whether the objects are equal is judged by whether the contents of the objects are equal .
// String 类 equals 源码
public boolean equals(Object anObject) {
    
    
    if (this == anObject) {
    
    
        return true;
    }
    if (anObject instanceof String) {
    
    
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
    
    
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
    
    
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
    }
判断相等的步骤:
1. 比较两个String对象是否为同一对象,如果是就直接返回true
2. 如果不是同一对象,先确定传入的对象是否是String类型,如果是,则比较两对象的字符序列
3. 遍历过程中只要有一个字符不相同,就返回false,否则返回true

Supplement : Covering equals needs to comply with popular conventions

  • Reflexivity : For any non-null reference value x, x.equals(x) must return true
  • Symmetry : For any non-null reference value x and y, if and only if y.equals(x) returns true, x.equals(y) must return true
  • Transitivity : For any non-null reference value x, y, z, if x.equals(y) is true and y.equals(z) also returns true, then x.equals(z) must also return true
  • Consistency : For any non-null reference values ​​x and y, as long as the information used in the object for the equals comparison operation has not been modified, multiple calls to x.equals(y) will consistently return true or false
  • For any non-null reference value x, x.equals(null) must return false

3.HashCode

The return value of the hashCode method is Int type data, and this value is called a hash code (hash code) . Role: Determine the index position of the object in the hash table.

  // Object 类的源码
  public native int hashCode();
application

In Java, a collection can store a large amount of data, so the elements in the Set collection are unordered and non-repeatable, so how does the Set collection ensure that the elements are not repeated? Check whether equals() is equal through iteration. A small amount of data is acceptable, and the efficiency can be imagined when we have a large amount of data. hashCode provides the solution.

HashCode is a local method, and its implementation is related to the local machine. When we add an element to a collection, the collection will first call the hashCode method, so that it can directly locate the location where it is stored, and if there are no other elements, it will be saved directly. If there is already an element there, the equals method is called to match whether the two elements are the same, the same will not exist, and the difference will be hashed to another location. In this way, when we store a large number of elements, we can greatly reduce the number of calls to the equals() method, which greatly improves efficiency.

The relationship between hashCode method and equals method

In Java, when using collection frameworks such as HashMap, HashSet, and HashTable, for example, use your own new class as the key of HashMap. In this case, you need to rewrite the hashCode and equals methods .
example

public class EqHashCode {
    
    

	public static void main(String[] args) {
    
    
		Student stu=new Student("小米","一班");
		Student stu1=new Student("小米","一班");

		HashMap<Student, String> hashMap = new HashMap<>();
		hashMap.put(stu,stu.className);
		hashMap.put(stu1,stu1.className);

		System.out.println(hashMap.size());
		System.out.println(stu==stu1);
		System.out.println(stu.equals(stu1));
	}

}

public class Student {
    
    
	public String name;
	public String className;

	public Student(String name, String className) {
    
    
		super();
		this.name = name;
		this.className = className;
	}

	@Override
	public boolean equals(Object obj) {
    
    
		if (this == obj) {
    
    
			return true;
		}

		if (obj instanceof Student) {
    
    
			Student stu = (Student) obj;
			if (name.equals(stu.name) && className.equals(stu.className)) {
    
    
				return true;
			}
		}

		return false;
	}

	@Override
	public int hashCode() {
    
    
		int result = 17;// 非0 任选
		result = 31 * result + name.hashCode();
		result = 31 * result + className.hashCode();
		return result;
	}

}
运行结果:
第一次equals 方法没有覆盖情况下,hashMap size为2;第二次覆盖equals 方法下,hashMap size为1
to sum up
  1. If the two objects are equal, the hashcode must also be the same
  2. If the two objects are equal, the equals method of the two objects respectively returns true
  3. Two objects have the same hashcode value, they are not necessarily equal
  4. The equals method is overridden, the hashCode method must also be overridden
  5. The default behavior of hashCode() is to generate unique values ​​for objects on the heap. If hashCode() is not overridden, the two objects of this class will not be equal anyway (even if the two objects point to the same data)

Reference
You overridden hashcode and equals it, you must override hashCode method Why rewrite equals?

Guess you like

Origin blog.csdn.net/xufei5789651/article/details/106903346