Comparer deux chaînes de caractères en Java avec des valeurs possibles null

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

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

Edit:

return ((str1 == str2) || (str1 != null && str1.equals(str2)));
115
demandé sur Boann 2012-06-30 08:58:47

11 réponses

c'est ce que Java internal code utilise (sur d'autres compare méthodes):

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

depuis Java 7, vous pouvez utiliser la méthode statique Objects.equals(Object, Object) pour effectuer des contrôles égaux sur deux objets sans vous soucier qu'ils soient null .

si les deux objets sont null il retournera true , si l'un est null et l'autre n'est pas il retournera false . Sinon il retournera le résultat de l'appel equals sur le premier objet avec le second comme argument.

170
répondu Mark Rotteveel 2016-04-19 08:25:35

pour ces cas , il serait préférable d'utiliser Apache Commons StringUtils#égale , il gère déjà des chaînes nulles. 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
répondu Luiggi Mendoza 2018-01-09 20:17:43

pour ceux sur android, qui ne peuvent pas utiliser les objets API 19.égal (str1, str2), il y a ceci:

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

c'est null safe. Il a rarement à utiliser la corde plus chère.la méthode equals () parce que les chaînes identiques sur android comparent presque toujours true avec le "==" opérande grâce à Android String Pooling , et les vérifications de longueur sont un moyen rapide de filtrer la plupart des inadéquats.

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
répondu 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 la comparaison de chaîne de sécurité nulle.

5
répondu 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);
}

c'est ce que vous vouliez?

2
répondu 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
répondu Kierrow 2012-06-30 05:06:01
boolean compare(String str1, String str2) {
  return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}
1
répondu 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
répondu Jobi Subramunian 2016-02-08 08:27:42

Compare deux chaînes de caractères 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
répondu 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 IMO le plus lisible est ce

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

en d'autres termes, masquer la mise en œuvre à l'intérieur d'une méthode simple qui (idéalement) peut être inlinée.

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


si vous voulez dire le plus performant, alors:

  1. la solution la plus performante dépend de la plateforme et du contexte,
  2. l'une des questions de" contexte "est la fréquence relative (dynamique) d'occurrence de null arguments,
  3. il probablement n'est pas n'importe quelle version est la plus rapide ... parce que la différence est probablement trop petit pour faire une différence dans la performance globale de l'application ,et
  4. si cela importe, la seule façon de savoir qui est le plus rapide sur votre plate-forme est d'essayer les deux versions et de mesurer la différence.
0
répondu Stephen C 2012-06-30 05:25:54