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)));
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));
}
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.
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.
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;
}
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.
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?
boolean compare(String str1, String str2) {
if (str1 == null || str2 == null)
return str1 == str2;
return str1.equals(str2);
}
boolean compare(String str1, String str2) {
return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}
Vous pouvez utiliser java.util.Objects
comme suit.
public static boolean compare(String str1, String str2) {
return Objects.equals(str1, str2);
}
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
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:
- la solution la plus performante dépend de la plateforme et du contexte,
- l'un des problèmes de "contexte" est la fréquence relative (dynamique) d'occurrence des
null
arguments, - 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
- 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.