2009-09-09 6 views
29

Existe-t-il une méthode dans le JDK qui compare deux objets pour l'égalité, en tenant compte des valeurs nulles? Quelque chose comme ceci:Comparer deux objets avec une vérification de null

public static boolean equals(Object o1, Object o2) 
{ 
    if (o1 == null) 
    { 
     return o2 == null; // Two nulls are considered equal 
    } 
    else if (o2 == null) 
    { 
     return false; 
    } 

    return o1.equals(o2); 
} 

Il semble stupide de me écrire cette méthode car je pense qu'il doit déjà exister quelque part.

Répondre

51

Java 7.0 a ajouté une nouvelle classe: Objects.

Il a une méthode exactement pour cela: Objects.equals(Object a, Object b)

+0

Eh bien, gardez à l'esprit que Java 7 n'est pas encore universellement disponible. J'essaie généralement de ne pas utiliser une API tant que son déploiement n'a pas atteint au moins 95%. –

+1

@EdwardFalk Oui, et gardez à l'esprit que Java 7 (ou toute autre version) n'atteindra jamais 100% de disponibilité. Aujourd'hui c'est le 12 juillet 2015, Java 7 a exactement 4 ans, Java 6 a ** 9 ans **. Même Java 7 a atteint ** la fin de vie **, ce qui signifie qu'il n'y aura plus de mises à jour publiques même pour Java 7. Pourquoi encouragez-vous à utiliser uniquement l'API Java 6.0? Oui, il y a des ordinateurs qui n'ont que Java 6.0, mais personnellement je ne veux pas développer de logiciel pour des systèmes vieux de dix ans, au détriment de l'abandon des fonctionnalités ajoutées dans Java 7 et 8. – icza

+0

Oui, c'est mon style de travail . J'ai seulement commencé à utiliser les fonctionnalités Java 6 au cours des dernières années, et je n'utilise pas encore les fonctionnalités Java 7 ou 8. J'ai été comme ça toute ma vie; Je n'ai pas commencé à utiliser Ansi C jusqu'à ce que K & R C ne soit plus disponible nulle part. J'utiliserai de nouvelles fonctionnalités quand j'en aurai besoin, mais chaque fois que possible, je préfère que mon code compile et fonctionne partout. –

4

Si vous êtes inquiet au sujet NullPointerExceptions vous pouvez simplement tester l'égalité comme:

if (obj1 != null && obj1.equals(obj2)) { ... } 

Le contrat général de equals() est qu'un objet non nul ne doit jamais être égale à une référence nulle, et que la méthode equals() devrait renvoyer false si vous comparez un objet à une référence null (et ne lancez pas un NPE).

+2

J'utilise cette logique dans d'autres scénarios, mais ici je veux en particulier deux nulls à considérer égale (et donc d'exécuter la vraie clause). Faire ceci en ligne serait plutôt verbeux: if ((obj1 == null && obj2 == null) || (obj1! = Null && obj1.equals (obj2))) {...} – dcstraw

+1

Ceci est l'un de ces Construit (comme vérifier une chaîne pour NULL et Vider ou fermer un flux sans se soucier d'une IOException) qui est difficile pour les yeux et pour lequel commun-lang a une solution. – SingleShot

+0

Je suis d'accord avec SingleShot et j'utilise souvent commons-lang pour des choses comme ça. –

17

Apache Commons Lang a une telle méthode: ObjectUtils.equals(object1, object2). Vous ne voulez pas de génériques sur une telle méthode, cela conduira à de fausses erreurs de compilation, au moins en général. Equals sait très bien (ou devrait - cela fait partie du contrat) de vérifier la classe de l'objet et renvoyer false, il n'a donc pas besoin de sécurité de type supplémentaire.

+0

Oui, je suppose que les génériques ne vous achètent rien dans ce cas. Vous pouvez toujours passer dans des types complètement différents et l'inférence de type sélectionnera simplement Object comme paramètre de type. Je ne suis pas sûr de ce que les "fausses erreurs de compilation" que vous faites référence sont bien. – dcstraw

+0

J'ai certainement vu des tentatives pour faire des génériques comme ça ont des problèmes (avec des paramètres génériques, et autres). Je ne pouvais pas le reproduire rapidement dans ce scénario, donc vous avez peut-être raison, mais si c'est le cas, alors les génériques sont inutiles, puisqu'ils accepteront n'importe quoi, alors pourquoi ne pas simplement déclarer Object? – Yishai

+1

D'accord. L'utilisation d'Object est meilleure dans ce cas. – dcstraw

2

Chaque fois que je rencontre un besoin et que je pense "c'est tellement commun que Java doit l'avoir" mais que je ne trouve pas ça, je vérifie le projet Jakarta Commons. Il l'a presque toujours. Une recherche rapide de l'API commons-lang (qui a le plus basique des utilitaires courants) montre une méthode equals() qui fournit ce que vous voulez.

14

FWIW, ce fut ma mise en œuvre:

private static boolean equals(Object a, Object b) { 
    return a == b || (a != null && a.equals(b)); 
} 

Dans ma demande, je sais que a et b sera toujours le même type, mais je suspecte que cela fonctionne bien même si ce n'est pas le cas, à condition que a.equals() soit raisonnablement mis en œuvre.

+2

La nouvelle méthode est 'Objects.equals (Object a, Object b)' – tmin

+1

Nouveau dans 1.7. Agréable. –

+0

'return (a == null)? (a == b): a.equals (b); 'semble tellement plus lisible que ce que vous avez là (même s'il appelle égal pour le même objet). – Dukeling

5
public static boolean equals(Object object1, Object object2) { 
    if (object1 == null || object2 == null) { 
     return object1 == object2; 
    } 
    return object1.equals(object2); 
}