Comparer deux chaînes en Java avec des valeurs null possibles


Je veux comparer deux chaînes pour l'égalité en Java, quand l'une ou l'autre pourrait être null, donc je ne peux pas simplement appeler .equals(). Quelle est la meilleure façon de faire?

boolean compare(String str1, String str2) {
    ...
}

Modifier:

return ((str1 == str2) || (str1 != null && str1.equals(str2)));
Author: Boann, 2012-06-30

11 answers

Voici ce que le code interne Java utilise (sur d'autres méthodes compare):

public static boolean compare(String str1, String str2) {
    return (str1 == null ? str2 == null : str1.equals(str2));
}
 135
Author: Eric, 2013-07-26 15:47:37

Depuis Java 7, vous pouvez utiliser la méthode statique Objects.equals(Object, Object) effectuer des contrôles égaux sur deux objets sans se soucier de leur être null.

Si les deux objets sont null, il retournera true, si l'un est null et un autre ne l'est pas, il retournera false. Sinon, il sera de retour le résultat de l'appel equals sur le premier objet avec le deuxième argument.

 170
Author: Mark Rotteveel, 2016-04-19 08:25:35

Pour ces cas, il serait préférable d'utiliser Apache Commons StringUtils#est égal à, déjà, elle gère des chaînes vides. Exemple de code:

public boolean compare(String s1, String s2) {
    return StringUtils.equals(s1, s2);
}

Si vous ne voulez pas ajouter la bibliothèque, copiez simplement le code source de la méthode StringUtils#equals et appliquez-le quand vous en avez besoin.

 35
Author: Luiggi Mendoza, 2018-01-09 20:17:43

Pour ceux sur Android, qui ne peuvent pas utiliser les objets de l'API 19.equals(str1, str2), il y a ceci:

android.text.TextUtils.equals(str1, str2);

, Il est nul en sécurité. Il doit rarement utiliser la chaîne la plus chère.méthode equals () parce que les chaînes identiques sur Android comparent presque toujours true avec l'opérande "= = " grâce à le pool de chaînes d'Android, et les vérifications de longueur sont un moyen rapide de filtrer la plupart des incompatibilités.

Code source:

/**
 * Returns true if a and b are equal, including if they are both null.
 * <p><i>Note: In platform versions 1.1 and earlier, this method only worked  well if
 * both the arguments were instances of String.</i></p>
 * @param a first CharSequence to check
 * @param b second CharSequence to check
 * @return true if a and b are equal
 */
public static boolean equals(CharSequence a, CharSequence b) {
    if (a == b) return true;
    int length;
    if (a != null && b != null && (length = a.length()) == b.length()) {
        if (a instanceof String && b instanceof String) {
            return a.equals(b);
        } else {
            for (int i = 0; i < length; i++) {
                if (a.charAt(i) != b.charAt(i)) return false;
            }
            return true;
        }
    }
    return false;
}
 23
Author: NameSpace, 2016-08-04 09:28:31

Depuis la version 3.5 Apache Commons StringUtils a les méthodes suivantes:

static int  compare(String str1, String str2)
static int  compare(String str1, String str2, boolean nullIsLess)
static int  compareIgnoreCase(String str1, String str2)
static int  compareIgnoreCase(String str1, String str2, boolean nullIsLess)

Ceux-ci fournissent une comparaison de chaînes sans danger null.

 5
Author: phn, 2016-11-22 15:15:03
boolean compare(String str1, String str2) {
    if(str1==null || str2==null) {
        //return false; if you assume null not equal to null
        return str1==str2;
    }
    return str1.equals(str2);
}

Est-ce ce que vous souhaitiez?

 2
Author: didxga, 2012-06-30 08:21:04
boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}
 1
Author: Kierrow, 2012-06-30 05:06:01
boolean compare(String str1, String str2) {
  return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}
 1
Author: Sumit Singh, 2012-06-30 05:10:29

Vous pouvez utiliser java.util.Objects comme suit.

public static boolean compare(String str1, String str2) {
    return Objects.equals(str1, str2);
}
 1
Author: Jobi Subramunian, 2016-02-08 08:27:42

Comparez deux chaînes en utilisant la méthode equals(-,-) et equalsIgnoreCase(-,-) de la classe Apache Commons StringUtils.

StringUtils.est égal à(-, -) :

StringUtils.equals(null, null)   = true
StringUtils.equals(null, "abc")  = false
StringUtils.equals("abc", null)  = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false

StringUtils.equalsIgnoreCase(-, -) :

StringUtils.equalsIgnoreCase(null, null)   = true
StringUtils.equalsIgnoreCase(null, "abc")  = false
StringUtils.equalsIgnoreCase("xyz", null)  = false
StringUtils.equalsIgnoreCase("xyz", "xyz") = true
StringUtils.equalsIgnoreCase("xyz", "XYZ") = true
 1
Author: Prashant Sahoo, 2018-06-10 13:20:32

OK, alors que signifie "meilleure solution possible"?

Si vous voulez dire le plus lisible, alors toutes les solutions possibles sont à peu près équivalentes pour un programmeur Java expérimenté. Mais l'OMI le plus lisible est ceci

 public boolean compareStringsOrNulls(String str1, String str2) {
     // Implement it how you like
 }

En d'autres termes, cachez l'implémentation dans une méthode simple qui (idéalement) peut être intégrée.

(Vous pouvez également "out-source" vers une bibliothèque d'utilitaires tierce ... si vous utilisez déjà dans votre base de code.)


Si vous voulez dire le plus performant, puis:

  1. la solution la plus performante dépend de la plateforme et du contexte,
  2. l'un des problèmes de "contexte" est la fréquence relative (dynamique) d'occurrence des null arguments,
  3. il probablement peu importe quelle version est plus rapide ... parce que la différence est probablement trop faible pour faire une différence sur les performances globales de l'application, et
  4. si cela a de l'importance, la seule façon de savoir lequel est le plus rapide SUR VOTRE PLATE-forme est d'essayer les deux versions et mesurer la différence.
 0
Author: Stephen C, 2012-06-30 05:25:54