Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.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 为什么';t String.equals检查char[]值是否相等?_Java_String_Performance_Micro Optimization - Fatal编程技术网

Java 为什么';t String.equals检查char[]值是否相等?

Java 为什么';t String.equals检查char[]值是否相等?,java,string,performance,micro-optimization,Java,String,Performance,Micro Optimization,我正在查看java.lang.String的源代码,注意到没有检查支持每个字符串的char[]是否是同一个对象。这不是比以前更好吗 此重写版本中包含的假定改进: public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anoth

我正在查看
java.lang.String
的源代码,注意到没有检查支持每个字符串的
char[]
是否是同一个对象。这不是比以前更好吗

此重写版本中包含的假定改进:

public boolean equals(Object anObject) {
       if (this == anObject) {
           return true;
       }
       if (anObject instanceof String) {
           String anotherString = (String)anObject;
           int n = count;
           if (n == anotherString.count) {
               char v1[] = value;
               char v2[] = anotherString.value;
               int i = offset;
               int j = anotherString.offset;
               /** Begin Optimization **/
               if(v1==v2 && i==j){
                   return true;
               }
               /** End Optimization **/
               while (n-- != 0) {
                   if (v1[i++] != v2[j++])
                       return false;
               }
               return true;
           }
       }
       return false;
   }
我相信,如果这两个字符串是使用
String.substring
获得的,甚至可能是内部字符串,那么这将提高性能

有人知道他们选择不这样做是有原因的吗

更新:对于可能不太了解的任何人来说,除了字符串池之外,在其他情况下,两个字符串对象可以具有相同的char[]值、int offset和int count

考虑以下代码:

String x = "I am a String, yo!";
String y = x.split(" ")[3];
String z = x.substring(7,14);
你会遇到这样的情况:


显然,在Java7U6中,字符串的值共享特性已经被取消,以满足一些基准测试。因此,如果您花时间使用String.substring()而不是字符串串联来让代码在适当的时间内运行(或根本不运行),您就完蛋了。

在Java 7(),
substring()
不再对返回的
字符串使用相同的后备数组。您仍然需要检查每个字符。基本上,
String
backing
char[]
永远不会被共享,所以您不能

this.value == other.value

您需要检查
char[]
偏移量
计数(字符串长度)。由于
char[]
仅从
String
类中创建,因此这三个值相等的唯一方法是
String
从自身创建一个doppelgänger。您可以让它这样做(例如,
新字符串(“为什么?”)
),但这不是常见的用例


我甚至不确定它是否能加快速度。绝大多数情况下,支票都会失败,这意味着它做额外的工作没有任何好处。这可能会被分支预测所抵消,但在这种情况下,检查通过的次数很少,它将使分支预测所做的猜测无效,这实际上可能会减慢速度。换言之,如果JVM/CPU试图针对常见情况进行优化,您通常不会获得任何好处,而在极少数情况下(这正是您试图优化的情况),您实际上会伤害自己。如果它不尝试优化这种常见的情况,那么在大多数比较中,你会为了一组相当罕见的比较而伤害自己<代码>

我不明白这个问题。
char[]
字符串的内部成员。如果两个字符串引用相同(应该是因为您应该使用intern字符串),则char[]将是相同的。
但是对于不同的实例,为什么希望
char[]
是相同的引用?字符串是不可变的,两个不同的字符串对象不可能共享对同一备份数组的引用。
此外,即使对子字符串使用此条件检查也没有意义。
我不知道其中一个答案中提到的Java 7中的变化,但在这种情况下检查备份数组的相等性是错误的。
字符串对象不仅是背景数组,而且是其当前偏移量、长度等。

因此,作为子字符串的结果,2个字符串对象可能由相同的字符数组支持,但很可能包含不同的(子)-字符串作为内容-相同字符数组中的不同偏移量

对支持字符数组进行这样的检查很可能是多余的,并且不是必需的

有两种情况下,支持字符数组对象可以是相同的对象(因为其他点子字符串方法总是创建新的支持字符数组)

定义字符串文字

String a = "Hello";
a.equals("Hello"); // Backing array of "Hello" string literal 
                   // will be same as that of variable a
在本例中,equals方法将在检查backing char数组之前确定下一行的字符串是否相等

if (this == anObject) { // From String.equals method
    return true;
}
使用字符串复制构造函数创建另一个字符串对象

请注意,下面的代码块没有实际价值,永远无法在实际代码中完成

String a = "Hello;
String b = new String(a);
a.equals(b);

因此,与其做额外的检查来确定字符数组是否相同,不如假设字符串对象不同,它们总是不同的。

这样做的方法是比较每个字符。可能没有意义,因为总是使用
clone()
arrays在Java 7之前的极少数情况下,它可能会提高性能,例如
foo.substring(i,j).equals(foo.substring(i,j))
——但是当字符串数组不相等时,它也会对更常见的情况进行额外检查,这似乎平均花费的时间比节省的时间要多。参见例如…@SotiriosDelimanolis我不是在问他们是否平等;我在问它们是否是同一个对象。@LouisWasserman我想说,这个优化和他的示例之间最重要的区别是,这将通过运行多个O(1)行代码(1或2个比较,取决于我们有多幸运)来防止O(n)操作;虽然他的示例只是防止在n=0或n=1(本质上)的情况下进行O(n)操作。那么,您的意思是,在Java 7中,它创建了后台数组的副本,而不是使用相同的备份数组?但是,您可以将该代码替换为
Java.util.array.equals(value,other.value)
@gparyani Yes,调用的构造函数使用
数组。copyOfRange
@gparyani equals方法非常等效。我有点怀疑;您链接到的那篇文章没有引用任何源代码,并且查看,它肯定会一如既往地运行(shared char[])。count已经被检查为围绕我的代码的if()块的条件。如果某些字符串是由相同字符串的子字符串生成的,那么它们将具有相同的char[],并且可能具有