2015-11-06 5 views
11

In JDK 8, String.equals Geräte alsString.Equals Implementierung

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; 
} 

Warum wird die Iteration zwei Operationen verwendet - Erhöhen i und Erniedrigen n anstatt etwas wie folgt aus:

while (i < n) { 
    if (v1[i] != v2[i]) 
     return false; 
    i++; 
} 

oder

while (i-- != 0) { 
    if (v1[i] != v2[i]) 
     return false; 
} 

mit einem Inkrement t oder dekrementieren Operation?

Ich nehme an, es ist irgendwie mit JVM Bytecode-Optimierung verwandt, aber verstehe nicht, wie.

+1

[Verbunden] (http://Stackoverflow.com/q/12661335/1743880) – Tunaki

+1

@Thilo Sie haben Recht. Habe diesen Punkt verpasst. – SubOptimal

+0

Wenn dies eine Art von cleverer Optimierung ist (kann nicht sehen, wie), ist es eine, die sie entschieden haben, nicht für 'Arrays.equals' zu verwenden. 'Arrays.equals' verwendet nur die offensichtliche 'for'-Schleife. –

Antwort

5

Ich denke, das ist toter Code, übrig von den Tagen als Strings immer noch Backing-Arrays geteilt und hatten offset und count, so dass Sie die Indizes ein wenig zwicken mussten.

Die String-Implementierung wurde in JDK 7 Update 6 geändert (viele Leute waren darüber verärgert, vor allem, dass es in einer Nebenversion passiert ist). Strings teilen nicht mehr das Backing-Array (es sei denn, die Strings sind selbst gleich. In diesem Fall versucht ein neuer Deduplizierer, sie erneut zu teilen).

Sie können eine Diskussion der alten Implementierung über "how does String.equals() work" sehen.

+1

Ein weiterer interessanter Aspekt ist, dass equals den Hashcode der Strings nicht verwendet. Dies wird unter http://stackoverflow.com/questions/14262431/why-does-the-equals-method-in-string-not-use-hash?lq=1 beschrieben. – Thilo

+0

Und jetzt, da die Arrays nicht mehr geteilt werden, Man könnte auch die Objektidentität für die beiden Arrays vergleichen ("if (value == anotherString.value) gibt true zurück"). Ich nehme an, das passiert nicht viel. – Thilo

+0

Haben sie das nicht schon gemacht, wenn sie die Identität der Strings vergleichen? –

0

Eigentlich hat dieser Java-Code keine direkte Beziehung zu echtem Maschinencode (zumindest für moderne Desktop/Server-JVM). Sie können über "Intrinsic Methoden in HotSpot VM" lesen. Z.B. When will JVM use intrinsics