String.isEmpty () veya “” .equals (string) kullanmalı mıyım?


171

Başlık temelde her şeyi söylüyor. Bunu genellikle a ile birlikte test string == nullediyorum, bu yüzden gerçekten güvenli bir testle ilgilenmiyorum. Hangisini kullanmalıyım?

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

veya

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

Bu notta - ya da isEmpty()dışında bir şey yapıyor mu?return this.equals("");return this.length() == 0;


26
isEmpty()Yalnızca Java 6+ olduğunu unutmayın .
ColinD

1
Tüm durumları işlemek için boş, boşluk ve boşluk olup olmadığını kontrol eden yardımcı bir yöntem olan Util.String.hasValue (String s) yapabilirsiniz.
Cloudanger

5
@ColinD Muhtemelen bir sorun değil - J2SE 5.0, Servis Sonu ömrünü bir süre önce tamamladı.
Tom Hawtin - tackline

1
Dikkate alınması gereken başka bir şey de "" .equals (), Object'i bağımsız değişken olarak alır; bu nedenle, bağımsız değişken türü Dize'den başka bir şeye daha iyi veya daha kötü bir şekilde değişirse derleyici hatası almazsınız.
Paul Jackson

Yanıtlar:


251

Ana parası "".equals(s)Eğer yok ise gerek (boş çek equalsonun argüman ve getiri kontrol edecek falsegöründüğün 's boş ise), umurumda değil. Eğer snull olma konusunda endişelenmiyorsanız (ya da başka şekilde kontrol ediyorsanız), kesinlikle kullanırım s.isEmpty(); tam olarak neyi kontrol ettiğinizi gösterir s, boş dizeye eşit olup olmadığını önemsemezsiniz


29
Açıklama için teşekkürler. Şimdi neden str.equals ("") yerine "" .equals (str) tercih etmeyi biliyorum! Her zaman başkalarının bunu neden bu kadar sık ​​kullandığını merak ediyordum, ama null değerleri hesaba katmadım. Harika :-)
Peter Wippermann

10
IMHO, yukarıdaki örneklerde koşulun null değeri için doğru olması gerektiğini varsaydığımızdan hala null kontrolü gereklidir. s == null || "" .equals (s)
mkorpela

5
@ Master.Aurora hayır, getValue()null döndürülürse toString(), çağrıldığında bir NullPointerException alırsınız
ataulm

12
@RenniePet Herhangi bir sihir varmış gibi değil. Eğer snull, üzerinde yöntemleri çağırmak olamaz - 's boş. ""asla boş olmayacaktır, bu yüzden yöntemleri güvenli bir şekilde çağırabilir equals()ve argümanının boş olduğu durumla başa çıkabilirsiniz
Michael Mrozek

5
Performansla ilgili bir not: isEmpty()özel bir dizinin iç uzunluğunu denetlerken equals(Object anObject)daha fazlasını yapar (örn. Denetleme instanceof). Perfromance-wise, isEmpty()genellikle daha hızlıdır.
Turing85

82

String.equals("")aslında bir isEmpty()çağrıdan biraz daha yavaştır . Dizeler değişmez olduğu için yapıcıda başlatılan bir sayı değişkeni saklar.

isEmpty() count değişkenini 0 ile karşılaştırırken, eşittir türleri, dize uzunluğunu kontrol eder ve boyutlar eşleşirse karşılaştırma için dize üzerinden yineleme yapar.

Yani sorunuzu cevaplamak için, isEmpty()aslında çok daha az yapacak! ve bu iyi bir şey.


3
Bu durumda farkın geçerli olmadığını düşünüyorum; karşılaştırmak için dizeler üzerinde asla bir yineleme olmayacaktır, çünkü boyutlar eşleşmeyecektir (dize gerçekten boş değilse ve daha sonra yinelenecek karakter yoksa)
Michael Mrozek

2
Doğru ama eşittir önce aynı nesne olup olmadığını görmek için bir başvuru denetimi, sonra bir instanceof, sonra bir String, bir uzunluk denetimi ve son olarak yineleme bakın. Her iki Dize de boş olsaydı, o zaman sadece basit bir referans kontrolü olurdu.
David Young

String sınıfının kaynak kodu kullanılabilir java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/…
David Young

1
@David ölü bağlantı; İşte canlı bir docjar.com/html/api/java/lang/String.java.html#1011
Matt Ball

17

Bahsedilen diğer sorunların yanı sıra dikkate almak isteyebileceğiniz bir şey isEmpty(), 1.6'da tanıtıldığı için, onu kullanırsanız, Java 1.5 veya daha düşük bir sürümde kodu çalıştıramazsınız.


4
Bu kesinlikle benim için bir endişe değil.
Matt Ball

1
Ayrıca, bu cevap şimdi 6 yıl önce. Artık hiç kimsenin Java 1.5 gibi eski bir şeyi kullanması gerekmediğini umuyorum.
Misha Nasledov

1
Aslında, bir java sürümünü yükseltirken kırılabilecek birçok şey var. Büyük bir sunucuda çalışan bir arka uç uygulaması için daha az kritiktir, ancak istemci uygulamaları için önemlidir. Grafik kütüphaneleri ve çöp toplama stratejileri büyük ve küçük java güncellemelerinden sık sık etkilenmektedir. Bunun da ötesinde, istemci yazılımı çeşitli işletim sistemlerinde ve bazen sınırlı bellekle çalışabilir, bu da genellikle her şeyi test etmek için bütçeye / kaynaklara sahip olmayacağınız anlamına gelir. - Evet, 2017'de hala Java 5 ile uyumlu müşterilerim var.
bvdb

15

StringUtils isEmpty () veya isNotEmpty () apache commons kullanabilirsiniz .


1
@ 2019 ve bunun için hala bir 3. parti kütüphanesine ihtiyacımız var: iç çekiş:
Adam

2

Gerçekten önemli değil. "".equals(str)bence daha açık.

isEmpty()döner count == 0;


47
str.isEmpty()Daha net olduğunu söyleyebilirim "".equals(str). Ne kontrol ettiğinizi okur. Sanırım görüş meselesi.
ColinD

7
Bazı insanlar NPE önlemek için "" .equals (str) yapmayı tercih düşünüyorum. Şahsen ben sevmiyorum çünkü ben ilk başta dize olup olmadığını kontrol etmek istiyorum.
CoolBeans

2

Performansı test edebilecek bir testçi sınıfı yazdım:

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

.İsEmpty () kullanmanın .equals ("") süresinin yaklaşık yarısını aldığını buldum.


Bu geçerli bir mikrobenchmark değil. Kaliper veya benzeri bir amaca yönelik kıyaslama aracı kullanmanızı şiddetle tavsiye ederim . stackoverflow.com/q/504103/139010
Matt Ball

Bahşiş için teşekkürler! Biraz boş zaman bulduğumda, bazı mikro karşılaştırmaları deneyeceğim ve cevabımı güncelleyeceğim.
conapart3
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.