我应该使用string.isEmpty()还是“” .equals(string)?


171

标题基本上说明了一切。我通常会在的同时进行测试string == null,因此我并不真正担心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
您可以创建一个辅助方法Util.String.hasValue(String s),该方法检查null,空值和空格以处理所有情况。
Cloudanger 2010年

5
@ColinD可能不是问题-J2SE 5.0在一段时间之前完成了其服务寿命。
Tom Hawtin-大头钉

1
要考虑的另一件事是“” .equals()将Object作为参数,因此,如果参数类型从String更改为其他类型(无论好坏),都不会出现编译器错误。
保罗·杰克逊

Answers:


251

"".equals(s)这样做的主要好处是您不需要进行null检查(equals将检查其参数,false如果为null则返回),这似乎并不在乎。如果您不担心s为空(或检查它是否为空),我肯定会使用s.isEmpty();它准确显示您要检查的内容,您在乎是否s为空,而不是是否等于空字符串


29
谢谢你的解释。现在我知道为什么相对于str.equals(“”)偏爱“” .equals(str)了!我一直想知道为什么其他人如此频繁地使用它,却没有考虑空值。太棒了:-)
彼得·威珀曼

10
恕我直言,在上述示例中仍需要进行空检查,因为我们假设空值的条件应为true。s == null || “” .equals(s)
mkorpela 2014年

5
@ Master.Aurora否,如果getValue()返回null,toString()则在调用时会收到NullPointerException
ataulm 2014年

12
@RenniePet好像没有涉及任何魔术。如果s为null,则不能在其上调用方法-它为null。""永远不会为null,因此您可以安全地对其调用方法,并且equals()可以处理其参数为null的情况
Michael Mrozek 2014年

5
关于性能的说明:isEmpty()检查私有数组的内部长度,而equals(Object anObject)做更多(例如检查instanceof)。性能方面,isEmpty()通常更快。
Turing85

82

String.equals("")实际上比isEmpty()通话要慢一些。字符串存储在构造函数中初始化的计数变量,因为字符串是不可变的。

isEmpty() 比较count变量为0,而equals将检查类型,字符串长度,然后在大小匹配的情况下遍历字符串以进行比较。

因此,回答您的问题isEmpty()实际上将减少很多工作!那是一件好事。


3
我认为在这种情况下,差异并不适用。不会有重复的字符串进行比较,因为大小不会匹配(除非字符串实际上为空,然后没有要迭代的字符)
Michael Mrozek 2010年

2
是的,但等于true时,您首先需要进行引用检查,以查看它们是否是同一对象,然后是instanceof,然后是强制转换为String,进行长度检查,最后是迭代。如果两个字符串都为空,则只是一个简单的引用检查。
David Young,2010年


1
@David死链接;这是一个现场直播docjar.com/html/api/java/lang/String.java.html#1011
Matt Ball

17

除了提到的其他问题之外,您可能还需要考虑的一件事是isEmpty()1.6中引入的,因此,如果使用它,您将无法在Java 1.5或更低版本上运行代码。


4
这绝对不是我关心的问题。
马特·鲍尔

1
另外,这个答案现在是6年前。我希望没有人再使用Java 1.5之类的古老工具了。
Misha Nasledov '16

1
实际上,升级Java版本时可能会破坏很多事情。对于在大型服务器上运行的后端应用程序而言,它的重要性不那么重要,但对于客户端应用程序而言却至关重要。图形库和垃圾回收策略通常受主要和次要Java升级的影响。最重要的是,客户端软件可以在各种操作系统上运行,有时内存有限,这意味着您通常没有预算/资源来测试所有内容。-是的,我的客户在2017
Java5。– bvdb

15

您可以使用Apache Commons StringUtils isEmpty()或isNotEmpty()。


1
@ 2019,我们仍然需要一个第三方图书馆:叹息:
亚当

2

没关系。"".equals(str)我认为更清楚。

isEmpty()回报count == 0;


47
我想说str.isEmpty()的要比清楚得多"".equals(str)。它显示为您要检查的内容。我想是意见问题。
ColinD

7
我认为有些人喜欢使用“ .equals(str)来避免NPE。我个人不喜欢它,因为我宁愿先检查字符串是否不为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
马特·鲍尔

谢谢你的提示!当我有空闲时间时,我将尝试一些微基准测试并更新我的答案。
conapart3'1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.