Comparaison de valeurs longues en Java

1. Vue d'ensemble

Dans ce court didacticiel, nous aborderons différentes manières de comparer deux instances Long . Nous soulignons les problèmes qui se posent lors de l'utilisation de l'opérateur de comparaison de référence ( == ).

2. Problème lors de l'utilisation de la comparaison de références

Long est une classe wrapper pour le type primitif long . Puisqu'il s'agit d'objets et non de valeurs primitives, nous devons comparer le contenu des instances Long en utilisant .equals () au lieu de l'opérateur de comparaison de référence (==).

Dans certains cas, nous pouvons avoir l'idée que == est correct, mais les apparences sont trompeuses. Considérez que nous pouvons utiliser == avec des nombres faibles:

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

mais pas avec des nombres plus grands. Nous finirions par avoir des problèmes si les valeurs sont hors de la plage -128 à 127, avec un résultat complètement différent et inattendu:

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

En effet, Java maintient un pool constant pour les instances de Long entre -128 et 127.

Cette optimisation, cependant, ne nous donne pas une licence pour utiliser ==. Dans le cas général, deux instances encadrées ayant la même valeur primitive ne donnent pas la même référence d'objet.

3. Utilisation de .equals ()

Une des solutions consiste à utiliser le .equals () . Cela évaluera le contenu (et non la référence) des deux objets:

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

4. Objects.equals ()

Le problème avec l'utilisation de equals () est que nous devons faire attention à ne pas l'appeler sur la référence nulle .

Heureusement, il existe une méthode utilitaire de sécurité nulle que nous pouvons utiliser - Objects.equals ().

Voyons comment cela fonctionne dans la pratique:

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

Comme nous pouvons le voir, nous n'avons pas besoin de nous soucier si l'un des Longs que nous voulons comparer est nul.

Sous le capot, Objects.equals () utilise d'abord l'opérateur == pour la comparaison, et si cela échoue, il utilise un standard equals ().

5. Déballage des valeurs longues

5.1. Utilisation de la .longValue () Méthode

Ensuite, utilisons l'opérateur de comparaison «==», mais de manière sûre. La classe Number a une méthode .longValue () qui déballe la valeur longue primitive :

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

5.2. Casting aux valeurs primitives

Une autre façon de déballer un Long consiste à convertir les objets en types primitifs. Par conséquent, nous allons extraire la valeur primitive, puis nous pouvons continuer à utiliser l'opérateur de comparaison:

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

Notez que, pour la méthode .longValue () ou en utilisant le cast , nous devons vérifier si l'objet est nul . Nous pourrions avoir une NullPointerException si l'objet est nul .

6. Conclusion

Dans ce court didacticiel, nous avons exploré différentes options pour comparer des objets longs . Nous avons analysé les différences lors de la comparaison des références aux objets ou au contenu.

Comme toujours, le code source complet de l'article est disponible à l'adresse over sur GitHub.