# equals() and hashCode() basic knowledge learning

equals() and hashCode() detailed study

  • The Object class is the parent class of each class, and all objects implement the methods defined in Object. equals()、hashCode()They are java.lang.Objectthe methods in.

equals()

Equals() in Object class
public boolean equals(Object obj) {
    
    
    return (this == obj);
}

Use the equal sign to determine whether two objects are equal, and the representation of the object in memory is identification (memory address) and state (data).

Equal sign ==and equals()equality problem
  • The equal sign compares whether the memory addresses of two objects are equal.
  • equals() compares whether the contents of the object are equal.

Example 1

String a = "123";
String b = "123";
System.out.println(a==b?"yes":"no");
  • The way a and b are created may or may not create an object. If the assigned string does not exist in the java String pool, an a="123"object will be created in the String pool , and then a and b will point to this memory address, and then When created in this way, only one address is always assigned.

The output result in example 1 should be yes, because a==b judges whether the addresses of the objects are equal, and the comprehensive analysis at this time the addresses of a and b are equal.

Example 2

String c = new String("123");
String d = new String( "123");
System.out.println(c==d?"yes":"no");
  • new String()At least one object will be created, and it is also possible to create two. An object of c will be created in the heap, and if the string does not exist in the String pool. "123"This object will be created in the String pool .

The output result in Example 2 is No, which is new String()related. At this time, use == to judge when the addresses of the two objects are different, so the value is no.

Rewrite equals() for classes such as String
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;
}

hashCode()

The hashCode() method returns a hash code value to the object. This method is used in hash tables.

  • If they equal(Object)are equal according to the method, then calling the two hashCode()methods must produce the same int result.

  • When the equals method is rewritten, it is usually necessary to rewrite the hashCode method to maintain the conventional contract of the hashCode method, which states that equal objects must have equal hash codes.

The definition of hashCode() method in Object class

public native int hashCode();
  • The existence of hashCode is mainly used for the quickness of search, such as Hashtable, HashMap, etc., hashCode is used to determine the storage address of the object in the hash storage structure.

Override equals() and hashCode()

public class User {
    
    

    private int id;
    private String name;
    private String address;

    public User(int id, String name, String address) {
    
    
        this.id = id;
        this.name = name;
        this.address = address;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) {
    
    
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
    
    
            return false;
        }
        User user = (User) o;
        return id == user.id &&
                Objects.equals(name, user.name) &&
                Objects.equals(address, user.address);
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(id, name, address);
    }
    
    // setget()省略
}

If only the equals() method is overridden, then num is null. The object pointed to by user and the new object in map.get() are two objects, and their storage addresses are different.

@Test
public void test1(){
    
    
    User user = new User(1,"张三","test1");
    System.out.printf(String.valueOf(user.hashCode()));

    HashMap<User,Integer> map = new HashMap<>(16);
    map.put(user,23);

    System.out.print("=======");
    Integer num = map.get(new User(1, "张三", "test1"));
    System.out.printf(String.valueOf(num));

}
HashMap的get()
  • get() method, if getNode() is Null, get() returns null.
  • getNode ()
    • Hash is the hash of the key, and the formal parameter key is the key
public V get(Object key) {
    
    
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

final Node<K,V> getNode(int hash, Object key) {
    
    
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    // 成员变量table不为空,且table的长度大于0,并且经过hash函数计算的存储单元不为空
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
    
    
        // 第一个节点的hash值等于hash 且第一个节点的key等于key
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            // 返回第一个节点
            return first;
        // 该存储单元链接了多个节点
        if ((e = first.next) != null) {
    
    
            // 节点以红黑树的方式连接
            // 第一个节点的类型是树节点类型
            if (first instanceof TreeNode)
                // 调用红黑树中查找的方法
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            // 循环的方式在链表中查找
            do {
    
    
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    // 找不到返回null
    return null;
}

Guess you like

Origin blog.csdn.net/qq_37248504/article/details/110007064