哪个String方法:"contains"或"indexOf> -1"?

sas*_*ank 45 java string substring

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

if (str.indexOf("/") > -1)
Run Code Online (Sandbox Code Playgroud)

要么

if (str.contains("/")) 
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 92

看一下java.lang.String源代码.该contains方法使用调用来实现indexOf,因此它们基本相同.

public boolean contains(CharSequence s) {
    return indexOf(s.toString()) > -1;
}
Run Code Online (Sandbox Code Playgroud)

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


编辑:

一些答案提到indexOf应该优先考虑,contains因为这contains会产生额外的方法调用,因此效率较低.这是错的.在这种情况下由额外的方法调用引起的开销是完全无关紧要的.使用在您的实现环境中最有意义的方法.这将使您的代码更具可读性.

  • "在这种情况下由额外的方法调用引起的开销是完全无关紧要的." 你能解释一下为什么会这样吗?字节码优化?其他一些原因.对于外行来说,看起来调用堆栈上的额外层会使*有些*差异.Juts好奇为什么你说它微不足道.谢谢. (11认同)
  • 额外的额外方法调用不一定是无关紧要的.我猜你是假设JIT编译器要内联它,但这并不能保证,并且并非所有java编译器都使用JIT编译.因此,"这是错误的"一个单独的声明是错误的. (2认同)

Ted*_*ung 22

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

# 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
Run Code Online (Sandbox Code Playgroud)

请注意,每次操作的基准测量值为纳秒.因此,比较包含("z")与indexOf("z"),indexOf()非常快,但小于0.6ns.有趣的是,间接(使用变量)的差异略大于1ns.

我在GitHub上放置了这个基准测试的代码:https://github.com/tedyoung/indexof-contains-benchmark


Pet*_*ser 5

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