Confronta due stringhe in Java con possibili valori null
Voglio confrontare due stringhe per l'uguaglianza in Java, quando una o entrambe potrebbero essere null
, quindi non posso semplicemente chiamare .equals()
. Qual è il modo migliore?
boolean compare(String str1, String str2) {
...
}
Modifica:
return ((str1 == str2) || (str1 != null && str1.equals(str2)));
11 answers
Questo è ciò che usa il codice interno Java (su altri metodi compare
):
public static boolean compare(String str1, String str2) {
return (str1 == null ? str2 == null : str1.equals(str2));
}
Da Java 7 è possibile utilizzare il metodo statico Objects.equals(Object, Object)
per eseguire controlli uguali su due oggetti senza preoccuparsi che siano null
.
Se entrambi gli oggetti sono null
restituirà true
, se uno è null
e un altro no restituirà false
. Altrimenti restituirà il risultato della chiamata equals
sul primo oggetto con il secondo come argomento.
Per questi casi sarebbe meglio usare Apache Commons StringUtils # equals, gestisce già stringhe null. Esempio di codice:
public boolean compare(String s1, String s2) {
return StringUtils.equals(s1, s2);
}
Se non vuoi aggiungere la libreria, copia il codice sorgente del metodo StringUtils#equals
e applicalo quando ne hai bisogno.
Per quelli su Android, che non possono utilizzare gli oggetti dell'API 19.equals (str1, str2), c'è questo:
android.text.TextUtils.equals(str1, str2);
È null sicuro. Raramente deve usare la stringa più costosa.metodo equals () perché le stringhe identiche su Android si confrontano quasi sempre con l'operando "= = " grazie a Il pool di stringhe di Android e i controlli di lunghezza sono un modo veloce per filtrare la maggior parte dei disallineamenti.
Codice sorgente:
/**
* 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;
}
Dalla versione 3.5 Apache Commons StringUtils ha i seguenti metodi:
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)
Forniscono un confronto di stringhe null sicuro.
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);
}
È questo ciò che desideravi?
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);
}
Puoi usare java.util.Objects
come segue.
public static boolean compare(String str1, String str2) {
return Objects.equals(str1, str2);
}
Confrontare due stringa utilizzando equals(-,-) e equalsIgnoreCase(-,-) metodo di Apache Commons StringUtils classe.
StringUtils.uguale(-, -) :
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.Equalesignorecase(-, -) :
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, quindi cosa significa "migliore soluzione possibile"?
Se intendi più leggibile, allora tutte le possibili soluzioni sono praticamente equivalenti per un programmatore Java esperto. Ma IMO il più leggibile è questo
public boolean compareStringsOrNulls(String str1, String str2) {
// Implement it how you like
}
In altre parole, nascondere l'implementazione all'interno di un metodo semplice che (idealmente) può essere inline.
(Potresti anche "out-source" in una libreria di utilità di terze parti ... se lo usi già nella tua base di codice.)
Se intendi più performante, quindi:
- la soluzione più performante dipende dalla piattaforma e dal contesto,
- uno dei problemi di "contesto" è la frequenza relativa (dinamica) di occorrenza degli argomenti
null
, - esso probabilmente non importa quale versione è più veloce ... perché la differenza è probabilmente troppo piccola per fare la differenza per le prestazioni complessive dell'applicazione e
- se è importante, l'unico modo per capire quale è il più veloce SULLA TUA PIATTAFORMA è provare entrambe le versioni e misurare la differenza.