# equals () e hashCode () aprendizado de conhecimento básico

estudo detalhado equals () e hashCode ()

  • A classe Object é a classe pai de cada classe, e todos os objetos implementam os métodos definidos em Object. equals()、hashCode()Eles são java.lang.Objectos métodos em.

é igual a()

Equals () na classe Object
public boolean equals(Object obj) {
    
    
    return (this == obj);
}

Use o sinal de igual para determinar se dois objetos são iguais e a representação do objeto na memória é a identificação (endereço de memória) e o estado (dados).

Sinal de igualdade ==e equals()problema de igualdade
  • O sinal de igual compara se os endereços de memória de dois objetos são iguais.
  • equals () compara se o conteúdo do objeto é igual.

Exemplo 1

String a = "123";
String b = "123";
System.out.println(a==b?"yes":"no");
  • A maneira como a e b são criados pode ou não criar um objeto. Se a string atribuída não existir no conjunto de strings java, um a="123"objeto será criado no conjunto de strings e, em seguida, aeb apontarão para este endereço de memória, e então Quando criado desta forma, apenas um endereço é sempre atribuído.

O resultado de saída no exemplo 1 deve ser sim, porque a == b julga se os endereços dos objetos são iguais e os endereços de aeb são iguais neste momento por meio de uma análise abrangente.

Exemplo 2

String c = new String("123");
String d = new String( "123");
System.out.println(c==d?"yes":"no");
  • new String()Pelo menos um objeto será criado e é possível criar dois.Um objeto de c será criado no heap, e se a string não existir no pool de String. "123"Este objeto será criado no pool String .

O resultado de saída no Exemplo 2 é Não, que está new String()relacionado. Neste momento, use == para julgar quando os endereços dos dois objetos são diferentes, então o valor é não.

Reescreva equals () para classes como 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 ()

O método hashCode () retorna um valor de código hash para o objeto.Este método é usado em tabelas hash.

  • Se eles equal(Object)forem iguais de acordo com o método, chamar os dois hashCode()métodos deve produzir o mesmo resultado interno.

  • Quando o método equals é reescrito, geralmente é necessário reescrever o método hashCode para manter o contrato convencional do método hashCode, que afirma que objetos iguais devem ter códigos hash iguais.

A definição do método hashCode () na classe Object

public native int hashCode();
  • A existência de hashCode é usada principalmente para a rapidez da pesquisa, como Hashtable, HashMap, etc. O hashCode é usado para determinar o endereço de armazenamento do objeto na estrutura de armazenamento de hash.

Substituir equals () e 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()省略
}

Se apenas o método equals () for substituído, num será nulo. O objeto apontado pelo usuário e o novo objeto em map.get () são dois objetos e seus endereços de armazenamento são diferentes.

@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 e get ()
  • método get (), se getNode () for Nulo, get () retornará nulo.
  • getNode ()
    • Hash é o hash da chave, e o parâmetro formal chave é a chave
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;
}

Acho que você gosta

Origin blog.csdn.net/qq_37248504/article/details/110007064
Recomendado
Clasificación