【问题标题】:Should I use string.isEmpty() or "".equals(string)?我应该使用 string.isEmpty() 还是 "".equals(string)?
【发布时间】:2011-03-20 06:56:30
【问题描述】:

我通常与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; 之外还做其他事情吗?

【问题讨论】:

  • 请记住,isEmpty() 仅适用于 Java 6+。
  • 您可以创建一个辅助方法 Util.String.hasValue(String s) 来检查 null、空和空格来处理所有情况。
  • @ColinD 可能不是问题 - J2SE 5.0 前段时间结束了其服务生命周期。
  • 要考虑的另一件事是 "".equals() 将 Object 作为参数,因此如果参数类型从 String 更改为其他类型,无论好坏,您都不会收到编译器错误。

标签: java string


【解决方案1】:

这并不重要。 "".equals(str) 在我看来更清楚。

isEmpty() 返回count == 0

【讨论】:

  • 我想说str.isEmpty()"".equals(str) 清晰得多。它读作您正在检查的内容。不过我猜是意见问题。
  • 我认为有些人更喜欢使用 "".equals(str) 来避免 NPE。我个人不喜欢它,因为我宁愿先检查字符串是否不为空。
  • @CoolBeans 是的。话虽如此,问题是:所以我并不真正关心 null 安全测试
【解决方案2】:

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

【讨论】:

  • 感谢您的解释。现在我知道为什么偏爱 "".equals(str) 而不是 str.equals("")!我一直想知道为什么其他人经常使用它,但没有考虑空值。太棒了:-)
  • 恕我直言,在上面的示例中仍然需要进行空检查,因为我们假设空值的条件应该为真。 s == 空 || "".equals(s)
  • @Master.Aurora no,如果getValue() 返回null,当toString() 被调用时你会得到一个NullPointerException
  • @RenniePet 好像没有任何魔法。如果s 为空,则不能对其调用方法——它为空。 "" 永远不会为空,因此您可以安全地调用它的方法,equals() 可以处理其参数为空的情况
  • 关于性能的说明:isEmpty() 检查私有数组的内部长度,而 equals(Object anObject) 做得更多(例如检查 instanceof)。性能方面,isEmpty() 通常更快。
【解决方案3】:

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

【讨论】:

  • 这对我来说绝对不是问题。
  • 另外,这个答案现在是 6 年前。我希望没有人必须再使用像 Java 1.5 这样古老的东西了。
  • 事实上,在升级 java 版本时有很多事情会破坏。对于在大型服务器上运行的后端应用程序来说,它并不那么重要,但对于客户端应用程序来说却很重要。图形库和垃圾收集策略经常受到主要和次要 Java 升级的影响。最重要的是,客户端软件可以在各种操作系统上运行,有时内存有限,这意味着您通常没有预算/资源来测试所有内容。 - 是的,我有一些客户在 2017 年仍然坚持使用 Java 5。
【解决方案4】:

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

isEmpty() 将 count 变量与 0 进行比较,而 equals 将检查类型、字符串长度,然后在大小匹配时遍历字符串进行比较。

所以要回答你的问题,isEmpty() 实际上会少很多!这是一件好事。

【讨论】:

  • 我认为在这种情况下差异不适用;永远不会对字符串进行迭代以进行比较,因为大小不匹配(除非字符串实际上是空的,然后没有字符可以迭代)
  • True 但使用 equals 你会首先进行引用检查以查看它们是否是同一个对象,然后是 instanceof,然后是转换为 String,长度检查,最后是迭代。如果两个字符串都是空的,那么它只是一个简单的参考检查。
  • @David 死链接;这是现场直播docjar.com/html/api/java/lang/String.java.html#1011
【解决方案5】:

您可以使用 apache commons StringUtils isEmpty() 或 isNotEmpty()。

【讨论】:

  • @2019 我们仍然需要一个第三方库来解决这个问题:sigh:
【解决方案6】:

我写了一个Tester 可以测试性能的类:

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
  • 感谢您的提示!当我有空闲时间时,我会尝试一些微基准测试并更新我的答案。
猜你喜欢
  • 2011-08-28
  • 2010-11-30
  • 2020-12-02
  • 2019-10-19
  • 1970-01-01
  • 2018-09-05
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多