哪个字符串方法:“包含”或“indexOf > -1”?

Posted

技术标签:

【中文标题】哪个字符串方法:“包含”或“indexOf > -1”?【英文标题】:Which String method: "contains" or "indexOf > -1"? 【发布时间】:2012-05-29 16:08:45 【问题描述】:

以下哪种方法是确定子字符串包含的有效方法?

if (str.indexOf("/") > -1)

if (str.contains("/")) 

【问题讨论】:

与效率无关,但为了代码清晰,我更喜欢 contains()。 【参考方案1】:

查看java.lang.String 源代码。 contains 方法是通过调用indexOf 实现的,因此它们本质上是相同的。

public boolean contains(CharSequence s) 
    return indexOf(s.toString()) > -1;

您应该使用使您的代码更具可读性的任何方法。如果要检查字符串是否包含特定子字符串,请使用contains。如果您要查找子字符串的起始索引,请使用indexOf


编辑:

一些答案​​提到 indexOf 应该优先于 contains,因为 contains 进行了额外的方法调用,因此效率较低。 这是错误的。 在这种情况下,由额外的方法调用引起的开销完全是微不足道的。使用在您的实施环境中最有意义的任何方法。这将使您的代码更具可读性。

【讨论】:

"在这种情况下,由额外的方法调用引起的开销完全是微不足道的。"你能解释一下为什么会这样吗?字节码优化?其他一些原因。对于外行来说,调用堆栈上的额外层似乎会产生一些的不同。只是好奇你为什么说它微不足道。谢谢。 额外的额外方法调用不一定无关紧要。我猜你假设 JIT 编译器将内联它,但这绝不是保证,也不是所有的 java 编译器都使用 JIT 编译。因此,“这是错误的”的简单声明是错误的。 直接搜索一个字符''怎么样,因为包含一个toString 如解释的开销问题没有意义,是的。但为了代码清晰,我更喜欢使用 contains ,但如果我们需要“第一次出现的索引”,那么将使用 indexOf 如果我们在超过一百万次重复的循环中使用 "if (str.contains("/"))" 会怎样?【参考方案2】:

我认为我会采用经验方法来解决这个问题,而不是猜测额外方法调用的开销将如何影响结果。我从this answer 中获取indexOf 基准,并为contains() 添加了两种基准方法(一种采用字符串常量,另一种采用变量)。我正在使用在 Windows x64 上运行的刚刚发布的 1.8.0_71。

# JMH 1.11.3 (released 8 days ago)
# VM version: JDK 1.8.0_71, VM 25.71-b15

Benchmark                           Mode  Cnt   Score   Error  Units
IndexOfTest.containsString          avgt   30  26.596 ± 0.099  ns/op
IndexOfTest.containsStringIndirect  avgt   30  28.683 ± 0.088  ns/op
IndexOfTest.indexOfChar             avgt   30  26.855 ± 0.171  ns/op
IndexOfTest.indexOfCharIndirect     avgt   30  25.833 ± 0.116  ns/op
IndexOfTest.indexOfString           avgt   30  26.192 ± 0.107  ns/op
IndexOfTest.indexOfStringIndirect   avgt   30  27.547 ± 0.152  ns/op

请注意,每次操作的基准测量为纳秒。因此比较 contains("z") 与 indexOf("z"),indexOf() 稍微快一点,但不到 0.6ns。有趣的是,间接(使用变量)的差异更大,略高于 1ns。

我已将此基准测试的代码放在 GitHub 上:https://github.com/tedyoung/indexof-contains-benchmark

【讨论】:

【参考方案3】:

如果目标是确定一个字符串是否包含另一个字符串,那么contains() 显然是赢家。这将使其他开发人员更有效地理解您的意图。

【讨论】:

【参考方案4】:

基本上两者都是一样的,

public boolean contains(CharSequence s) 
    return indexOf(s.toString()) > -1;

但是如果你想通过索引做一些事情,你可以使用indexOf

我相信indexOf会更高效,但区别可以忽略。

【讨论】:

【参考方案5】:

这些方法有不同的用途,如果您需要检查String是否包含某些内容,则使用contains,但如果您想知道它最终包含在String中的哪个位置,请使用indexOf方法。

【讨论】:

【参考方案6】:

虽然使用str.contains("/") 显然更具可读性,但使用str.indexOf('/') > -1 可能更有效。请注意,我在 indexOf 调用中使用字符而不是字符串。

但这在性能方面并不重要,除非您处于非常紧凑的循环中。

【讨论】:

【参考方案7】:

最近我在使用indexOf() 时遇到了这个问题:当试图找出字符串是否包含空格 以用其他东西替换它们时,IndexOf 的答案是:字符串没有空格,这是错误的答案。当替换为Contains() 答案是正确的。想想看,因为正如一些人所说,Contains()IndexOf 发布了一个电话。

【讨论】:

【参考方案8】:

对于单字符搜索,例如您的示例,indexOf 更有效如果 indexOf 的参数是一个字符

if (str.indexOf('/') > -1)

【讨论】:

以上是关于哪个字符串方法:“包含”或“indexOf > -1”?的主要内容,如果未能解决你的问题,请参考以下文章

String包含在Java哪个包里

对于一个或两个字符的字符串,哪个更有效:CHAR(2) 或 VARCHAR(2)?

哪个更快?修剪()或正则表达式?

关于检索关键字的常用四种方法

JAVA的XX.put中的put方法,是在哪个父类或祖父类中,详述父类链。

算法:有没有解决比较的好方法?