Dovrei usare string.isEmpty () o “” .equals (stringa)?


171

Il titolo praticamente dice tutto. Di solito sto testando questo insieme a a string == null, quindi non sono davvero preoccupato per un test nullo. Quale dovrei usare?

String s = /* whatever */;
...
if (s == null || "".equals(s))
{
    // handle some edge case here
}

o

if (s == null || s.isEmpty())
{
    // handle some edge case here
}

In quella nota - fa isEmpty()anche qualcosa di diverso da return this.equals("");o return this.length() == 0;?


26
Tieni presente che isEmpty()è solo Java 6+.
ColinD,

1
È possibile creare un metodo di supporto Util.String.hasValue (String s) che verifica la presenza di null, vuoto e spazi bianchi per gestire tutti i casi.
Cloudanger,

5
@ColinD Probabilmente non è un problema - J2SE 5.0 ha completato il suo periodo di fine servizio qualche tempo fa.
Tom Hawtin - tackline il

1
Un'altra cosa da considerare è "" .equals () prende Object come argomento, quindi non otterrai un errore del compilatore se il tipo di argomento cambia da String a qualcos'altro, nel bene e nel male.
Paul Jackson,

Risposte:


251

Il vantaggio principale "".equals(s)è che non è necessario il controllo null ( equalscontrollerà il suo argomento e restituirà falsese è null), di cui sembra non preoccuparsi. Se non sei preoccupato di sessere nullo (o stai controllando altrimenti), lo userei sicuramente s.isEmpty(); mostra esattamente cosa stai controllando, ti importa se sè vuoto o meno , non se è uguale alla stringa vuota


29
Grazie per la spiegazione. Ora so perché preferire "" .equals (str) rispetto a str.equals ("")! Mi chiedevo sempre perché gli altri lo usino così spesso, ma non hanno preso in considerazione valori nulli. Fantastico :-)
Peter Wippermann,

10
IMHO il controllo null è ancora necessario negli esempi precedenti poiché si assume che la condizione debba essere vera per il valore null. s == null || "" .equals (s)
mkorpela

5
@Master.Aurora no, se getValue()restituito null, otterrai una NullPointerException quando toString()veniva chiamato
ataulm

12
@RenniePet Non è come se fosse coinvolta qualche magia. Se sè null, non è possibile chiamare metodi su di esso - è null. ""non sarà mai nullo, quindi puoi chiamare metodi su di esso in modo sicuro e equals()gestire il caso in cui il suo argomento è nullo
Michael Mrozek,

5
Una nota sulle prestazioni: isEmpty()controlla la lunghezza interna di un array privato mentre equals(Object anObject)fa molto di più (ad es. Controllo instanceof). Per quanto riguarda le prestazioni, isEmpty()è generalmente più veloce.
Turing85,

82

String.equals("")è in realtà un po 'più lento di una semplice isEmpty()chiamata. Le stringhe memorizzano una variabile di conteggio inizializzata nel costruttore, poiché le stringhe sono immutabili.

isEmpty() confronta la variabile di conteggio su 0, mentre uguali controllerà il tipo, la lunghezza della stringa e quindi ripeterà la stringa per il confronto se le dimensioni corrispondono.

Quindi, per rispondere alla tua domanda, isEmpty()in realtà farà molto di meno! e questa è una buona cosa.


3
Penso che in questo caso la differenza non si applichi; non ci sarà mai un'iterazione sulle stringhe per il confronto, perché le dimensioni non corrisponderanno (a meno che la stringa non sia effettivamente vuota e quindi non ci siano caratteri su cui iterare)
Michael Mrozek,

2
Vero, ma con uguale si incorre in un controllo di riferimento prima per vedere se sono lo stesso oggetto, quindi un'istanza di, quindi un cast su String, un controllo di lunghezza e infine l'iterazione. Se entrambe le stringhe fossero vuote, sarebbe comunque solo un semplice controllo di riferimento.
David Young,

il codice sorgente della classe String è disponibile java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/…
David Young


17

Una cosa che potresti voler considerare oltre agli altri problemi citati è isEmpty()stata introdotta in 1.6, quindi se lo usi non sarai in grado di eseguire il codice su Java 1.5 o versioni precedenti.


4
Questo sicuramente non è un problema per me.
Matt Ball,

1
Inoltre, questa risposta è ora 6 anni fa. Spero che nessuno debba più usare qualcosa di antico come Java 1.5.
Misha Nasledov,

1
Ci sono infatti molte cose che possono rompersi durante l'aggiornamento di una versione java. È meno critico per un'applicazione back-end che viene eseguita su un server di grandi dimensioni, ma è importante per le applicazioni client. Le librerie grafiche e le strategie di garbage collection sono influenzate spesso da aggiornamenti java maggiori e minori. Inoltre, il software client può essere eseguito su vari sistemi operativi e talvolta con memoria limitata, il che significa che spesso non avrai il budget / le risorse per testare tutto. - Sì, ho clienti che continuano a utilizzare Java 5 nel 2017.
bvdb,


2

Non importa davvero. "".equals(str)è più chiaro secondo me.

isEmpty()ritorni count == 0;


47
Direi che str.isEmpty()è molto più chiaro di "".equals(str). Si legge come quello che stai controllando. Questione di opinioni, immagino.
ColinD,

7
Penso che alcune persone preferiscano fare "" .equals (str) per evitare NPE. Personalmente non mi piace perché preferirei prima controllare che la stringa non fosse nulla.
CoolBeans,

2

Ho scritto una classe di tester che può testare le prestazioni:

public class Tester
{
    public static void main(String[] args)
    {
        String text = "";

        int loopCount = 10000000;
        long startTime, endTime, duration1, duration2;

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.equals("");
        }
        endTime = System.nanoTime();
        duration1 = endTime - startTime;
        System.out.println(".equals(\"\") duration " +": \t" + duration1);

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.isEmpty();
        }
        endTime = System.nanoTime();
        duration2 = endTime - startTime;
        System.out.println(".isEmpty() duration "+": \t\t" + duration2);

        System.out.println("isEmpty() to equals(\"\") ratio: " + ((float)duration2 / (float)duration1));
    }
}

Ho scoperto che l'uso di .isEmpty () ha richiesto circa la metà del tempo di .equals ("").


Questo non è un microbenchmark valido. Consiglio vivamente di utilizzare Caliper o un analogo strumento di benchmarking appositamente costruito. stackoverflow.com/q/504103/139010
Matt Ball

Grazie per il consiglio! Quando avrò del tempo libero, sperimenterò alcuni micro benchmarking e aggiornerò la mia risposta.
conapart3,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.