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

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() . Quel est le meilleur moyen?

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

Modifier:

 return ((str1 == str2) || (str1 != null && str1.equals(str2))); 

C’est ce que Java code interne utilise (sur d’autres méthodes de compare ):

 public static boolean compare(Ssortingng str1, Ssortingng str2) { return (str1 == null ? str2 == null : str1.equals(str2)); } 

Depuis Java 7, vous pouvez utiliser la méthode statique Objects.equals(Object, Object) pour effectuer des vérifications égales sur deux objects sans se soucier de leur null .

Si les deux objects sont null elle retournera true , si l’un est null et qu’un autre ne l’est pas, il retournera false . Sinon, le résultat de l’appel des equals sur le premier object sera renvoyé avec le second argument.

Pour ces cas, il serait préférable d’utiliser Apache Commons SsortingngUtils # est égal à , il gère déjà les chaînes NULL. Échantillon de code:

 public boolean compare(Ssortingng s1, Ssortingng s2) { return SsortingngUtils.equals(s1, s2); } 

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

Pour ceux sur Android, qui ne peuvent pas utiliser Objects.equals (str1, str2) d’API 19, il y a ceci:

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

C’est nul en sécurité. Il doit rarement utiliser la méthode ssortingng.equals () plus coûteuse car les chaînes identiques sur android sont presque toujours vraies avec l’opérande “==” grâce au regroupement de chaînes d’ Android , et les contrôles de longueur permettent de filtrer rapidement la plupart des incohérences.

Code source:

 /** * Returns true if a and b are equal, including if they are both null. * 

Note: In platform versions 1.1 and earlier, this method only worked well if * both the arguments were instances of Ssortingng.

* @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 Ssortingng && b instanceof Ssortingng) { 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 SsortingngUtils a les méthodes suivantes:

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

Ceux-ci fournissent une comparaison de chaîne sécurisée nulle.

 boolean compare(Ssortingng str1, Ssortingng 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 avez désiré?

 boolean compare(Ssortingng str1, Ssortingng str2) { if (str1 == null || str2 == null) return str1 == str2; return str1.equals(str2); } 
 boolean compare(Ssortingng str1, Ssortingng str2) { return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2); } 

Vous pouvez utiliser java.util.Objects comme suit.

 public static boolean compare(Ssortingng str1, Ssortingng str2) { return Objects.equals(str1, str2); } 

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

SsortingngUtils.equals (-, -) :

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

SsortingngUtils.equalsIgnoreCase (-, -) :

 SsortingngUtils.equalsIgnoreCase(null, null) = true SsortingngUtils.equalsIgnoreCase(null, "abc") = false SsortingngUtils.equalsIgnoreCase("xyz", null) = false SsortingngUtils.equalsIgnoreCase("xyz", "xyz") = true SsortingngUtils.equalsIgnoreCase("xyz", "XYZ") = true 

OK, que veut dire “meilleure solution possible”?

Si vous voulez dire 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 ce

  public boolean compareSsortingngsOrNulls(Ssortingng str1, Ssortingng 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 “sous-traiter” une bibliothèque d’utilitaires tierce … si vous l’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’un des problèmes de “contexte” est la fréquence relative (dynamic) d’occurrence des arguments null ,
  3. peu importe la version qui est la plus rapide, car la différence est probablement trop petite pour faire une différence dans les performances globales de l’application, et
  4. Si tel est le cas, le seul moyen de déterminer lequel est le plus rapide SUR VOTRE PLATEFORME est d’essayer les deux versions et de mesurer la différence.