Comparación de valores largos en Java

1. Información general

En este breve tutorial, analizaremos diferentes formas de comparar dos instancias Long . Destacamos los problemas que surgen al utilizar el operador de comparación de referencia ( == ).

2. Problema al utilizar la comparación de referencias

Long es una clase contenedora para el tipo primitivo long . Dado que son objetos y no valores primitivos, necesitamos comparar el contenido de las instancias Long utilizando .equals () en lugar del operador de comparación de referencia (==).

En algunos casos, podemos tener la idea de que == está bien, pero las apariencias engañan. Considere que podemos usar == con números bajos:

Long l1 = 127L; Long l2 = 127L; assertThat(l1 == l2).isTrue();

pero no con números más grandes. Terminaríamos teniendo problemas si los valores están fuera del rango -128 a 127, teniendo un resultado completamente diferente e inesperado:

Long l1 = 128L; Long l2 = 128L; assertThat(l1 == l2).isFalse();

Esto se debe a que Java mantiene un grupo constante para instancias de Long entre -128 y 127.

Sin embargo, esta optimización no nos da una licencia para usar ==. En el caso general, dos instancias en caja que tienen el mismo valor primitivo no producen la misma referencia de objeto.

3. Usando .equals ()

Una de las soluciones es utilizar .equals () . Esto evaluará el contenido (y no la referencia) de ambos objetos:

Long l1 = 128L; Long l2 = 128L; assertThat(l1.equals(l2)).isTrue();

4. Objects.equals ()

El problema con el uso de equals () es que debemos tener cuidado de no llamarlo en la referencia nula .

Afortunadamente, hay un método de utilidad seguro nulo que podemos usar: Objects.equals ().

Veamos cómo funciona en la práctica:

Long l1 = null; Long l2 = 128L; assertThatCode(() -> Objects.equals(l1, l2)).doesNotThrowAnyException();

Como podemos ver, no necesitamos preocuparnos si alguno de los Long que queremos comparar es nulo.

Bajo el capó, Objects.equals () primero usa el operador == para la comparación, y si eso falla, usa un estándar igual ().

5. Desembalaje de valores largos

5.1. Uso de la .longValue () Método

A continuación, usemos el operador de comparación "==", pero de forma segura. La clase Number tiene un método .longValue () que desenvuelve el valor largo primitivo :

Long l1 = 128L; Long l2 = 128L; assertThat(l1.longValue() == l2.longValue()).isTrue();

5.2. Lanzar a valores primitivos

Una forma diferente de desempaquetar un Long es lanzando los objetos a tipos primitivos. Por lo tanto, extraeremos el valor primitivo y luego podemos proceder a usar el operador de comparación:

Long l1 = 128L; Long l2 = 128L; assertThat((long) l1 == (long) l2).isTrue();

Tenga en cuenta que, para el método .longValue () o el uso de conversión, debemos verificar si el objeto es nulo . Podríamos tener una NullPointerException si el objeto es nulo .

6. Conclusión

En este breve tutorial, hemos explorado diferentes opciones sobre cómo comparar objetos Long . Hemos analizado las diferencias al comparar referencias a objetos o contenido.

Como siempre, el código fuente completo del artículo está disponible en GitHub.