== operador, método igual y método hashCode en Java

1. == operador

== es un operador en Java, que se utiliza para comparar dos objetos, pero al comparar dos objetos, es necesario analizarlo según el tipo de comparación.

1.1 Tipos de datos básicos y tipos de datos básicos

Al comparar tipos de datos básicos a través de ==, sus tamaños se comparan directamente, independientemente de sus tipos específicos.

short num1 = 20000;
int num2 = 20000;
System.out.println(num1 == num2); // Output: true

1.2 Tipos de referencia y tipos de referencia.

Los tipos de referencia comparan sus direcciones de memoria, por lo que el resultado de comparar dos objetos del mismo tipo mediante == es generalmente falso.

public class Test {
    public static void main(String[] args) {
        Obj o1 = new Obj();
        Obj o2 = new Obj();
        System.out.println(o1 == o2); // Output: false
    }
}

class Obj {}

Pero no todas las situaciones devolverán falso: los tipos de referencia de los tipos de datos básicos tienen un mecanismo de agrupación constante, de modo que incluso si son dos objetos, seguirán apuntando al mismo espacio de memoria, es decir, seguirán siendo el mismo objeto.

Integer num1 = 100, num2 = 100;
System.out.println(num1 == num2); // Output: true

Para obtener más información, consulte: Ocho tipos básicos y sus tipos de embalaje.

1.3 Tipos de datos básicos y tipos de referencia

Al comparar tipos de datos básicos y tipos de referencia, si el tipo de referencia es numérico, entonces se puede realizar la comparación. No se pueden comparar otros tipos y se informará un error.

Integer num1 = 200;
int num2 = 200;
System.out.println(num1 == num2); // Output: true

int num = 200;
String str = "123";
System.out.println(str == num); // Error: 二元运算符 '==' 的操作数类型错误

2. método igual

Equals es un método básico de los tipos de referencia de Java. Sin anularlo, el método igual compara de forma predeterminada las direcciones de memoria de dos objetos. Después de anularlo, depende de la situación específica.

String str1 = "1";
String str2 = "2";
System.out.println(str1.equals(str2)); // Output: false

2.1 La diferencia entre el método igual y el operador ==

  • == es un operador, igual es un método del objeto (por lo que no existe un tipo de datos básico);
  • == Cuando se comparan tipos de datos básicos, es el valor comparado; cuando se comparan objetos, se compara su dirección de memoria;
  • De forma predeterminada, igual (no anulada) es la dirección de memoria del objeto de comparación y, después de anularla, es otro contenido (por ejemplo, Cadena es el valor del contenido representado por el objeto).

Tres, método de código hash

HashCode es un método muy especial que implica el conocimiento de las tablas hash. Hash se traduce como hash. Es un algoritmo que puede convertir rápidamente cualquier objeto en un valor hexadecimal. Entre diferentes objetos, los valores hash obtenidos a través del algoritmo hash serán No es lo mismo con una alta probabilidad. Hay una probabilidad muy pequeña de que sean iguales. En este momento, se produce una situación llamada "conflicto hash". Aquí, sin entrar en detalles al respecto, consulte: Algoritmo hash para detalles.

En resumen, en ausencia de un "conflicto hash", podemos juzgar si dos objetos son el mismo objeto a través de los diferentes valores hash de diferentes objetos.

String str1 = "1";
String str2 = "2";
System.out.println(str1.hashCode() == str2.hashCode()); // Output: false

Por supuesto, en circunstancias normales no utilizaremos el método hashCode como se indicó anteriormente, porque no hay garantía de que no se produzcan "conflictos hash". Aunque los valores hash de diferentes objetos pueden ser los mismos, la diferencia en los valores hash de dos objetos significa que deben ser diferentes. Por lo tanto, el valor hash se puede utilizar para determinar si dos objetos no son iguales.

4. Diferencias y conexiones

4.1 Diferencias

== generalmente se usa para determinar si los números son iguales, igual generalmente se usa para determinar si dos objetos son iguales y hashCode generalmente se usa para determinar si dos objetos son desiguales.

== solo compara números y es el más rápido de juzgar. Además, es el método hashCode, porque el cálculo de los valores hash es muy rápido. Finalmente, igual. Por defecto, igual compara las direcciones de memoria de dos objetos. Aunque Este proceso es muy rápido. La situación más general es que el método igual ha sido anulado y compara los valores de propiedad de dos objetos de tipo no numérico, por lo que es el más lento.

String str1 = "1";
String str2 = "1";
System.out.println(str1.equals(str2)); // Output: true

En el código anterior, el tipo de referencia incorporado String de Java anula el método igual, que compara el contenido de dos objetos String en lugar de las direcciones de memoria.

4.2 Contacto

== generalmente no tiene nada que ver con iguales y hashCode. Desde cierta perspectiva, no existe una conexión inevitable entre iguales y hashCode. Pero hay una estructura de datos en Java que vincula iguales y hashCode, es decir, HashMap y sus subclases.

Las claves en HashMap no se pueden repetir, por lo que sus claves deben ser objetos diferentes. En este momento, el hashCode, que es de cálculo rápido, se utiliza para comparar. Si los valores hash no son iguales, entonces los dos objetos no deben ser iguales. , si son iguales, entonces hay dos posibilidades para esto. Una situación es que los dos objetos son realmente iguales, y la otra situación es que ocurre un raro fenómeno de "conflicto hash", entonces es el turno de iguales en Esta vez ¡Es hora de juzgar! De esta forma, el problema de las claves no repetibles se soluciona de forma eficaz y rápida.

De la comparación de HashMap anterior, también podemos ver que cuando personalizamos el tipo, si queremos reescribir el método igual o el método hashCode, reescribamos ambos al mismo tiempo, porque la estructura de datos incorporada de Java, HashMap, determina si la clave es que la duplicación requiere llamar a ambos al mismo tiempo.

A modo de resumen, podemos resumirlo en la siguiente tabla:

método de comparación == operador método igual método de código hash
comparar velocidad rápido Rápido por defecto, lento en general medio
valor de comparación valor numérico El valor predeterminado es la dirección de memoria, generalmente un atributo de objeto. valor hash

4.3 Problemas clásicos

¿Por qué debería reescribir el método igual después de anular el método hashCode? ¿Habrá algún problema si solo anulo el método igual pero no el método hashCode? ¿Cómo se refleja en HashMap?

En HashMap las claves no se pueden repetir, es decir, sus claves son diferentes, por lo que es necesario determinar si diferentes objetos son el mismo objeto. Para resolver este problema, HashMap llama tanto al método igual como al método hashCode del objeto para su juicio. Parte del código fuente para el juicio es el siguiente:

if (e.hash == hash &&
    ((k = e.key) == key || (key != null && key.equals(k))))
    return e;

Tanto el método hashCode como el método equals se pueden utilizar para comparar dos objetos, pero existen algunas diferencias entre ellos:

método de comparación método igual método de código hash
comparar velocidad

De forma predeterminada, se comparan las direcciones de memoria, lo cual es rápido;

Después de reescribir, el contenido generalmente se compara y la velocidad es lenta.

Calcular valores hash, rápido
valor de comparación Dirección de memoria o contenido (atributo) valor hash

Por lo tanto, primero use el código hash con una velocidad de cálculo rápida para comparar, lo que puede resolver la mayoría de los problemas, pero debido a la posibilidad de "conflicto hash", también se necesita el método igual para resolverlo.

Solo porque es necesario llamar al método igual y al método hashCode al mismo tiempo para determinar si la clave se repite, debemos reescribirlos juntos al reescribirlos en la clase que definimos. Si solo anula el método igual pero no el método hashCode, cuando se crean y almacenan en HashMap dos objetos con el mismo contenido pero diferentes direcciones de memoria, se tratarán como dos claves en lugar de una clave, lo que provocará otros errores. .

Supongo que te gusta

Origin blog.csdn.net/weixin_62651706/article/details/132274016
Recomendado
Clasificación