string.isEmpty()または“” .equals(string)を使用する必要がありますか?


171

タイトルは基本的にそれをすべて言います。私は通常、と一緒string == nullにこれをテストしているので、ヌルセーフテストについてはあまり気にしていません。どちらを使用すればよいですか?

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

または

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

そのメモについて- またはisEmpty()以外のことも行いますか?return this.equals("");return this.length() == 0;


26
これisEmpty()はJava 6以降のみであることを覚えておいてください。
ColinD 2010

1
すべてのケースを処理するために、null、空、空白をチェックするヘルパーメソッドUtil.String.hasValue(String s)を作成できます。
Cloudanger、2010

5
@ColinDおそらく問題ありません-J2SE 5.0は、しばらく前にサービス終了期間を完了しました。
トム・ホーティン-10

1
もう1つの考慮事項は、 ""。equals()が引数としてObjectを取るため、引数の型がStringから他の何かに変更されても、コンパイラエラーは発生しません。
ポールジャクソン

回答:


251

主な利点は、"".equals(s)あなたがいないある必要はnullチェック(equals引数と戻りをチェックしfalse、あなたが気にしないように見えることの場合はnull)、。snullであることを心配していない(またはそれ以外の点でチェックしている)場合は、必ずを使用しs.isEmpty()ます。それはあなたがチェックしているものを正確に示します、sそれが空の文字列と等しいかどうかではなく、空であるかどうかを気にします


29
ご説明ありがとうございます。これで、 ".. equals(str)をstr.equals(" ")よりも優先する理由がわかりました。他の人がなぜこれを頻繁に使用するのかといつも思っていましたが、null値は考慮されていませんでした。素晴らしい:-)
Peter Wippermann、

10
上記の例では、NULL値に対して条件がtrueであると想定しているため、IMHOのnullチェックは依然として必要です。s == null || "" .equals(s)
mkorpela

5
@ Master.Auroraいいえ、getValue()nullが返された場合、toString()呼び出されたときにNullPointerExceptionが発生します
ataulm

12
@RenniePet魔法がかかっているようなものではありません。sがnullの場合、そのメソッドを呼び出すことはできません-nullです。""nullになることはないので、そのメソッドを安全に呼び出すことができequals()、引数がnullの場合も処理できます
Michael Mrozek

5
パフォーマンスに関する注記:isEmpty()一方、民間配列のチェックを内部長さがequals(Object anObject)はるかに(例えばチェックを行いますinstanceof)。パフォーマンスに関してisEmpty()は、一般的に高速です。
Turing85、2015

82

String.equals("")実際には、単なるisEmpty()呼び出しよりも少し遅いです。文字列は不変なので、文字列はコンストラクタで初期化されたカウント変数を格納します。

isEmpty() count変数を0と比較し、equalsはタイプと文字列の長さをチェックし、サイズが一致する場合は比較のために文字列を反復処理します。

だからあなたの質問に答えるために、isEmpty()実際にははるかに少ないです!それは良いことです


3
この場合、違いは当てはまらないと思います。サイズが一致しないため(比較のために文字列が実際に空でなく、次に反復する文字がない場合)、比較のために文字列の反復はありません
Michael Mrozek

2
Trueですが、equalsを使用すると、最初にそれらが同じオブジェクトかどうかを確認する参照チェックが行われ、次にinstanceof、次にStringへのキャスト、長さのチェック、最後に反復が行われます。両方の文字列が空の場合は、単純な参照チェックになります。
David Young

Stringクラスのソースコードが入手可能ですjava2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/...
デビッド・ヤング

1
@Davidデッドリンク。こちらがライブdocjar.com/html/api/java/lang/String.java.html#1011
Matt Ballです。

17

言及されている他の問題に加えて考慮したいことの1つはisEmpty()、1.6で導入されたものであるため、それを使用すると、Java 1.5以下でコードを実行できなくなります。


4
それは間違いなく私にとって問題ではありません。
マットボール

1
また、この答えは現在6年前です。Java 1.5のような古くからあるものを誰も使う必要がないことを願っています。
Misha Nasledov 2016

1
実際、Javaバージョンをアップグレードするときに壊れる可能性のある多くのものがあります。大きなサーバーで実行されるバックエンドアプリケーションの場合はそれほど重要ではありませんが、クライアントアプリケーションの場合は重要です。グラフィカルライブラリとガベージコレクション戦略は、メジャーおよびマイナーのJavaアップグレードの影響を受けることがよくあります。その上、クライアントソフトウェアはさまざまなオペレーティングシステムで実行でき、メモリが限られている場合もあります。つまり、すべてをテストするための予算やリソースがないことがよくあります。-はい、私はまだ2017年でJava 5にこだわるお客様に持っている
bvdb

15

Apache commonsのStringUtils isEmpty()またはisNotEmpty()を使用できます。


1
@ 2019でも、これにはサードパーティのライブラリが必要です:sigh:
Adam

2

それは本当に重要ではありません。"".equals(str)私の意見ではより明確です。

isEmpty()返すcount == 0;


47
str.isEmpty()よりもはるかに明確だと思います"".equals(str)。それはあなたがチェックしているものとして読みます。でも意見の問題ではないでしょうか。
ColinD 2010

7
NPEを回避するために "" .equals(str)を実行することを好む人もいると思います。文字列がnullでないことを最初に確認したいので、個人的には好きではありません。
CoolBeans 2010

2

パフォーマンスをテストできるテスタークラスを作成しました。

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

.isEmpty()を使用すると、.equals( "")の約半分の時間がかかることがわかりました。


これは有効なマイクロベンチマークではありません。Caliperまたは同様の専用のベンチマークツールを使用することを強くお勧めします。stackoverflow.com/q/504103/139010
Matt Ball

先端をありがとう!自由な時間になったら、マイクロベンチマークを試し、回答を更新します。
conapart3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.