Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中String.equals()的运行时复杂性_Java_String - Fatal编程技术网

Java中String.equals()的运行时复杂性

Java中String.equals()的运行时复杂性,java,string,Java,String,我想知道Java是如何实现String.equals()方法的,这种操作的运行时复杂性是多少。是否检查了每个单独的字符(导致O(N),其中N是长度),或者是否有某种有效的方法来比较这两个字符,从而得出O(1) 编辑: 当我看到另一个问题和答案时,我想知道Java是否有某种类型的自动内部调用,例如在初始化字符串或第一次调用compareTo或equals时兑现一些值,以允许几乎所有调用都是O(1)。如果我理解正确的话,答案是必须积极地插入字符串,Java在幕后什么都不做。String.equals

我想知道Java是如何实现String.equals()方法的,这种操作的运行时复杂性是多少。是否检查了每个单独的字符(导致O(N),其中N是长度),或者是否有某种有效的方法来比较这两个字符,从而得出O(1)

编辑:
当我看到另一个问题和答案时,我想知道Java是否有某种类型的自动内部调用,例如在初始化字符串或第一次调用compareTo或equals时兑现一些值,以允许几乎所有调用都是O(1)。如果我理解正确的话,答案是必须积极地插入字符串,Java在幕后什么都不做。

String.equals
首先比较引用。如果引用与
this
相同,则返回
true
。如果要比较的输入参数不是
String
type,则返回
false
。然后比较长度,如果两个字符串的长度不相同,则返回
false
。只有在这种情况下,复杂性才是O(1)


否则,该方法将比较两个
字符串的每个字符,这意味着它具有O(n)复杂度。

理论上它取决于实现,但是我不认为差异很大,对于
OpenJDK 7u40-b43
,这是实现

public boolean equals(Object anObject) {
    if (this == anObject) {
         return true;
     }
     if (anObject instanceof String) {
         String anotherString = (String) anObject;
         int n = value.length;
         if (n == anotherString.value.length) {
             char v1[] = value;
             char v2[] = anotherString.value;
             int i = 0;
             while (n-- != 0) {
                 if (v1[i] != v2[i])
                         return false;
                 i++;
             }
             return true;
         }
     }
     return false;
 }
正如您所看到的,它是O(n),但在以下任何情况下都有一些优化使其为Ω(1):

  • 字符串是同一个对象;或
  • 你检查的东西不是字符串;或
  • 字符串长度不同

您可以查看String.equals(String arg)的源代码;或者在Eclipse中运行一个调试器,并在其中附加源代码

我的快速检查显示字符串是逐字符比较的。

最有效的方法——几乎所有支持.equals()的Java对象的标准实践——是首先检查对象标识。如果两者为==,则根据定义它们为.equal()。这是O(1)

接下来,让对象根据其值实现一个(缓存的)hashcode,并在继续之前检查hashcode是否相等。对于实际测试,该快速案例为O(1)

在这种情况下,如果hashcode匹配,那么可以检查字符串长度,如果通过这种方式可以发现不匹配,那么字符串长度也将是O(1)

如果hashcode和长度匹配,那么您确实需要进行O(N)扫描以检查所有字符,然后才能说相等性已得到确认。(当然,如果它们不相等,它可能会更快地失败。)

所以,是的,在最坏的情况下,它必须被认为是O(N)。但在现实世界中,这种最坏的情况通常是可以避免的


(当然,如果您可以使用interned字符串,那么您可能只需要做身份测试就可以了。但这是另一个问题。)

源代码是免费提供的。@SotiriosDelimanolis是的,但可能取决于实现。假设所有的暗示都有一个特征,所以我不认为这个问题毫无价值。”UliK·奥勒接着读了java。它不能保证任何东西。@SotiriosDelimanolis有些特征可能没有提到。我也不认为是这样,但在任何情况下我都不会真的排除这种可能性。@UliKöhler-如果它不在规范中,你怎么知道这是真的。。。除了查看所有的实现之外?请记住,“可用”涉及价值判断。在不同的上下文中,可用性是不同的。如果字符串长度不相等,也会得到O(1)。注意:如果任何字符不同,它会很快消失。这使得它在大多数情况下都能有效地检测不同的字符串(除非字符串可能有很长的公共前缀)@paxdiablo:的确如此。这里没有O(1)或O(n)这样的东西,它是O(1)或O(n),在这种情况下,它是O(n),这是最坏的情况。当两个字符串相等时,最佳情况在大O表示法中不计算。