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)));
Author: Boann, 2012-06-30

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));
}
 135
Author: Eric, 2013-07-26 15:47:37

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.

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

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.

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

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;
}
 23
Author: NameSpace, 2016-08-04 09:28:31

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.

 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);
}

È questo ciò che desideravi?

 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

Puoi usare java.util.Objects come segue.

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

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
 1
Author: Prashant Sahoo, 2018-06-10 13:20:32

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:

  1. la soluzione più performante dipende dalla piattaforma e dal contesto,
  2. uno dei problemi di "contesto" è la frequenza relativa (dinamica) di occorrenza degli argomenti null,
  3. 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
  4. se è importante, l'unico modo per capire quale è il più veloce SULLA TUA PIATTAFORMA è provare entrambe le versioni e misurare la differenza.
 0
Author: Stephen C, 2012-06-30 05:25:54