array1.equals(array2)ist das gleiche wie array1 == array2, dh es ist das gleiche Array. Wie @alf betont, ist es nicht das, was die meisten Leute erwarten.
Arrays.equals(array1, array2) vergleicht den Inhalt der Arrays.
Ebenso array.toString()kann nicht sehr nützlich sein und Sie müssen verwenden Arrays.toString(array).
Beachten Sie, dass Arrays.equals()dies für mehrdimensionale Arrays nicht wie erwartet funktioniert, sondern nur Elemente der 1. Dimension auf Referenzgleichheit vergleicht. Apache Commons ArrayUtils.isEqualsarbeitet mit mehrdimensionalen Arrays.
Adam Parkin
4
Ich bin beeindruckt. Gibt es einen Grund dafür, dass array.equals für den Zeigervergleich implementiert wird, anstatt die Länge und jedes Objekt zu vergleichen?
See
2
@Lake is vergleicht zwar die Array-Länge und die enthaltenen Objekte, aber was es nicht tut, ist ein tiefer Vergleich. Die Tatsache, dass gleich wie erwartet für Arrays funktioniert, ist defekt, dies sollte überhaupt kein Problem sein.
@JeewanthaSamaraweera, das ist die Definition für diese Methode, aber .equalses vergleicht keine Inhalte, weshalb Sie diese Methode benötigen.
Peter Lawrey
86
Es ist ein berüchtigtes Problem: .equals()Da Arrays stark beschädigt sind, verwenden Sie sie niemals.
Das heißt, es ist nicht "kaputt" wie in "jemand hat es wirklich falsch gemacht" - es macht nur das, was definiert ist und nicht das, was normalerweise erwartet wird. Also für Puristen: Es ist vollkommen in Ordnung, und das bedeutet auch, es niemals zu benutzen.
Das erwartete Verhalten für equalsbesteht nun darin, Daten zu vergleichen. Das Standardverhalten besteht darin, die Identität zu vergleichen, da Objectkeine Daten vorhanden sind (für Puristen: Ja, aber es geht nicht darum). Annahme ist, wenn Sie equalsin Unterklassen benötigen , werden Sie es implementieren. In Arrays gibt es keine Implementierung für Sie, daher sollten Sie sie nicht verwenden.
Der Unterschied ist also, Arrays.equals(array1, array2)funktioniert wie erwartet (dh vergleicht Inhalt), array1.equals(array2)fällt zurück Object.equalsImplementierung, was wiederum Identität vergleicht, und somit eine bessere ersetzt durch ==(für Puristen: ja ich kenne null).
Das Problem ist, dass Sie sogar Arrays.equals(array1, array2)hart gebissen werden, wenn Elemente des Arrays nicht equalsrichtig implementiert werden. Ich weiß, es ist eine sehr naive Aussage, aber es gibt einen sehr wichtigen, weniger offensichtlichen Fall: Betrachten Sie ein 2D-Array.
2D-Array in Java ist ein Array von Arrays und Arrays ' equals sind defekt (oder nutzlos, wenn Sie dies bevorzugen), sodass Arrays.equals(array1, array2)sie bei 2D-Arrays nicht wie erwartet funktionieren.
Es ist nicht kaputt, es ist nur von Object geerbt.
Michael Borgwardt
Hat ein Array eine benutzerdefinierte Implementierung für equals()? Ich dachte, es wurde nicht von Object überschrieben.
Martijn Courteaux
@MichaelBorgwardt Es ist eine Systembibliothek mit einer Methode, die nicht das tut, was im Javadoc gesagt wird. Klingt für mich kaputt genug. Trotzdem gebe ich zu, dass es eine sehr umstrittene Aussage ist, aber ich glaube, dass "es ist kaputt" besser in Erinnerung bleibt und es daher viel bequemer ist, es so zu sehen.
alf
@ MartinijnCourteaux das ist genau das Problem :)
alf
3
Für Arrays von Arrays benötigen Sie Arrays.deepEquals--- es ist das, was someArray.equalsdie ganze Zeit hätte tun sollen. (Siehe auch : Objects.deepEquals.)
Kevin J. Chase
16
Schauen Sie sich die Implementierung der beiden Methoden an, um sie genau zu verstehen:
array1.equals(array2);
/**
* Indicates whether some other object is "equal to" this one.
* <p>
* The {@code equals} method implements an equivalence relation
* on non-null object references:
* <ul>
* <li>It is <i>reflexive</i>: for any non-null reference value
* {@code x}, {@code x.equals(x)} should return
* {@code true}.
* <li>It is <i>symmetric</i>: for any non-null reference values
* {@code x} and {@code y}, {@code x.equals(y)}
* should return {@code true} if and only if
* {@code y.equals(x)} returns {@code true}.
* <li>It is <i>transitive</i>: for any non-null reference values
* {@code x}, {@code y}, and {@code z}, if
* {@code x.equals(y)} returns {@code true} and
* {@code y.equals(z)} returns {@code true}, then
* {@code x.equals(z)} should return {@code true}.
* <li>It is <i>consistent</i>: for any non-null reference values
* {@code x} and {@code y}, multiple invocations of
* {@code x.equals(y)} consistently return {@code true}
* or consistently return {@code false}, provided no
* information used in {@code equals} comparisons on the
* objects is modified.
* <li>For any non-null reference value {@code x},
* {@code x.equals(null)} should return {@code false}.
* </ul>
* <p>
* The {@code equals} method for class {@code Object} implements
* the most discriminating possible equivalence relation on objects;
* that is, for any non-null reference values {@code x} and
* {@code y}, this method returns {@code true} if and only
* if {@code x} and {@code y} refer to the same object
* ({@code x == y} has the value {@code true}).
* <p>
* Note that it is generally necessary to override the {@code hashCode}
* method whenever this method is overridden, so as to maintain the
* general contract for the {@code hashCode} method, which states
* that equal objects must have equal hash codes.
*
* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/publicboolean equals(Object obj){return(this== obj);}
während:
Arrays.equals(array1, array2);
/**
* Returns <tt>true</tt> if the two specified arrays of Objects are
* <i>equal</i> to one another. The two arrays are considered equal if
* both arrays contain the same number of elements, and all corresponding
* pairs of elements in the two arrays are equal. Two objects <tt>e1</tt>
* and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null
* : e1.equals(e2))</tt>. In other words, the two arrays are equal if
* they contain the same elements in the same order. Also, two array
* references are considered equal if both are <tt>null</tt>.<p>
*
* @param a one array to be tested for equality
* @param a2 the other array to be tested for equality
* @return <tt>true</tt> if the two arrays are equal
*/publicstaticboolean equals(Object[] a,Object[] a2){if(a==a2)returntrue;if(a==null|| a2==null)returnfalse;int length = a.length;if(a2.length != length)returnfalse;for(int i=0; i<length; i++){Object o1 = a[i];Object o2 = a2[i];if(!(o1==null? o2==null: o1.equals(o2)))returnfalse;}returntrue;}
Seufzer. In den 70er Jahren war ich der "Systemprogrammierer" (sysadmin) für ein IBM 370-System, und mein Arbeitgeber war Mitglied der IBM-Benutzergruppe SHARE. Es kam manchmal vor, dass jemand einen APAR (Fehlerbericht) über ein unerwartetes Verhalten eines CMS-Befehls übermittelte und IBM auf NOTABUG antwortete: Der Befehl macht das, wofür er entwickelt wurde (und was in der Dokumentation steht).
SHARE hat sich einen Zähler dafür ausgedacht: BAD - Broken As Designed. Ich denke, dies könnte für diese Implementierung von Equals for Arrays gelten.
An der Implementierung von Object.equals ist nichts auszusetzen. Das Objekt hat keine Datenelemente, daher gibt es nichts zu vergleichen. Zwei "Objekte" sind genau dann gleich, wenn sie tatsächlich dasselbe Objekt sind (intern dieselbe Adresse und Länge).
Diese Logik gilt jedoch nicht für Arrays. Arrays haben Daten, und Sie erwarten einen Vergleich (über Gleichheit), um die Daten zu vergleichen. Idealerweise so wie Arrays.deepEquals, aber zumindest so wie Arrays.equals (flacher Vergleich der Elemente).
Das Problem ist also, dass das Array (als integriertes Objekt) Object.equals nicht überschreibt. String (als benannte Klasse) tut überschreiben Object.equals und geben Sie das Ergebnis Sie erwarten.
Andere Antworten sind richtig: [...]. Equals ([....]) vergleicht einfach die Zeiger und nicht den Inhalt. Vielleicht wird irgendwann jemand das korrigieren. Oder vielleicht auch nicht: Wie viele bestehende Programme würden kaputt gehen, wenn [...] tatsächlich die Elemente verglichen würden? Ich vermute, nicht viele, aber mehr als null.
Überprüfen Sie, ob beide Arrays die gleiche Anzahl von Elementen enthalten und alle entsprechenden Elementpaare in den beiden Arrays gleich sind.
Die array1.equals(array2):
Vergleichen Sie das Objekt mit einem anderen Objekt und geben Sie nur dann true zurück, wenn die Referenz der beiden Objekte gleich ist wie in der Object.equals()
Das equals()von Arrays wird von geerbt Object, sodass es nicht den Inhalt der Arrays betrachtet, sondern nur jedes Array als gleich betrachtet.
Die Arrays.equals()Methoden haben die Arrays' Inhalte vergleichen. Es gibt Überladungen für alle primitiven Typen, und die für Objekte verwendet die eigenen equals()Methoden der Objekte .
Sie sagen "Inhalt von Arrays". Bedeutet dies auch mehrdimensionale Arrays?
AlanFoster
@ AlanFoster: nein. Mehrdimensionale Arrays sind Arrays von Arrays, was bedeutet, dass die Methode Arrays.equals (Object [], Object []) aufgerufen wird, die die equals () -Methoden der Sub-Arrays aufruft
Michael Borgwardt
0
import java.util.Arrays;publicclassArrayDemo{publicstaticvoid main(String[] args){// initializing three object arraysObject[] array1 =newObject[]{1,123};Object[] array2 =newObject[]{1,123,22,4};Object[] array3 =newObject[]{1,123};// comparing array1 and array2boolean retval=Arrays.equals(array1, array2);System.out.println("array1 and array2 equal: "+ retval);System.out.println("array1 and array2 equal: "+ array1.equals(array2));// comparing array1 and array3boolean retval2=Arrays.equals(array1, array3);System.out.println("array1 and array3 equal: "+ retval2);System.out.println("array1 and array3 equal: "+ array1.equals(array3));}}
Hier ist die Ausgabe:
array1 and array2 equal:false
array1 and array2 equal:false
array1 and array3 equal:true
array1 and array3 equal:false
Wenn ich diese Art von Problem sehe, würde ich mich persönlich für Arrays.equals(array1, array2)Ihre Frage entscheiden, um Verwirrung zu vermeiden.
Es scheint richtig zu sein, aber bei Arrays ist auch die Reihenfolge der Elemente wichtig. Wenn Sie beispielsweise ein anderes Array haben Object [] array4 = new Object [] {123, 1}; Mit Arrays.equals (array3, array4) wird false zurückgegeben.
Antworten:
array1.equals(array2)
ist das gleiche wiearray1 == array2
, dh es ist das gleiche Array. Wie @alf betont, ist es nicht das, was die meisten Leute erwarten.Arrays.equals(array1, array2)
vergleicht den Inhalt der Arrays.Ebenso
array.toString()
kann nicht sehr nützlich sein und Sie müssen verwendenArrays.toString(array)
.quelle
Arrays.equals()
dies für mehrdimensionale Arrays nicht wie erwartet funktioniert, sondern nur Elemente der 1. Dimension auf Referenzgleichheit vergleicht. Apache CommonsArrayUtils.isEquals
arbeitet mit mehrdimensionalen Arrays.Arrays.deepEquals(Object[], Object[])
..equals
es vergleicht keine Inhalte, weshalb Sie diese Methode benötigen.Es ist ein berüchtigtes Problem:
.equals()
Da Arrays stark beschädigt sind, verwenden Sie sie niemals.Das heißt, es ist nicht "kaputt" wie in "jemand hat es wirklich falsch gemacht" - es macht nur das, was definiert ist und nicht das, was normalerweise erwartet wird. Also für Puristen: Es ist vollkommen in Ordnung, und das bedeutet auch, es niemals zu benutzen.
Das erwartete Verhalten für
equals
besteht nun darin, Daten zu vergleichen. Das Standardverhalten besteht darin, die Identität zu vergleichen, daObject
keine Daten vorhanden sind (für Puristen: Ja, aber es geht nicht darum). Annahme ist, wenn Sieequals
in Unterklassen benötigen , werden Sie es implementieren. In Arrays gibt es keine Implementierung für Sie, daher sollten Sie sie nicht verwenden.Der Unterschied ist also,
Arrays.equals(array1, array2)
funktioniert wie erwartet (dh vergleicht Inhalt),array1.equals(array2)
fällt zurückObject.equals
Implementierung, was wiederum Identität vergleicht, und somit eine bessere ersetzt durch==
(für Puristen: ja ich kennenull
).Das Problem ist, dass Sie sogar
Arrays.equals(array1, array2)
hart gebissen werden, wenn Elemente des Arrays nichtequals
richtig implementiert werden. Ich weiß, es ist eine sehr naive Aussage, aber es gibt einen sehr wichtigen, weniger offensichtlichen Fall: Betrachten Sie ein 2D-Array.2D-Array in Java ist ein Array von Arrays und Arrays '
equals
sind defekt (oder nutzlos, wenn Sie dies bevorzugen), sodassArrays.equals(array1, array2)
sie bei 2D-Arrays nicht wie erwartet funktionieren.Hoffentlich hilft das.
quelle
equals()
? Ich dachte, es wurde nicht von Object überschrieben.Arrays.deepEquals
--- es ist das, wassomeArray.equals
die ganze Zeit hätte tun sollen. (Siehe auch :Objects.deepEquals
.)Schauen Sie sich die Implementierung der beiden Methoden an, um sie genau zu verstehen:
während:
quelle
Seufzer. In den 70er Jahren war ich der "Systemprogrammierer" (sysadmin) für ein IBM 370-System, und mein Arbeitgeber war Mitglied der IBM-Benutzergruppe SHARE. Es kam manchmal vor, dass jemand einen APAR (Fehlerbericht) über ein unerwartetes Verhalten eines CMS-Befehls übermittelte und IBM auf NOTABUG antwortete: Der Befehl macht das, wofür er entwickelt wurde (und was in der Dokumentation steht).
SHARE hat sich einen Zähler dafür ausgedacht: BAD - Broken As Designed. Ich denke, dies könnte für diese Implementierung von Equals for Arrays gelten.
An der Implementierung von Object.equals ist nichts auszusetzen. Das Objekt hat keine Datenelemente, daher gibt es nichts zu vergleichen. Zwei "Objekte" sind genau dann gleich, wenn sie tatsächlich dasselbe Objekt sind (intern dieselbe Adresse und Länge).
Diese Logik gilt jedoch nicht für Arrays. Arrays haben Daten, und Sie erwarten einen Vergleich (über Gleichheit), um die Daten zu vergleichen. Idealerweise so wie Arrays.deepEquals, aber zumindest so wie Arrays.equals (flacher Vergleich der Elemente).
Das Problem ist also, dass das Array (als integriertes Objekt) Object.equals nicht überschreibt. String (als benannte Klasse) tut überschreiben Object.equals und geben Sie das Ergebnis Sie erwarten.
Andere Antworten sind richtig: [...]. Equals ([....]) vergleicht einfach die Zeiger und nicht den Inhalt. Vielleicht wird irgendwann jemand das korrigieren. Oder vielleicht auch nicht: Wie viele bestehende Programme würden kaputt gehen, wenn [...] tatsächlich die Elemente verglichen würden? Ich vermute, nicht viele, aber mehr als null.
quelle
Arrays erben
equals()
vonObject
und vergleichen daher nur true, wenn ein Array mit sich selbst verglichen wird.Arrays.equals
Vergleicht andererseits die Elemente der Arrays.Dieses Snippet verdeutlicht den Unterschied:
Siehe auch
Arrays.equals()
. Eine andere statische Methode kann ebenfalls von Interesse sein :Arrays.deepEquals()
.quelle
Die
Arrays.equals(array1, array2)
:Überprüfen Sie, ob beide Arrays die gleiche Anzahl von Elementen enthalten und alle entsprechenden Elementpaare in den beiden Arrays gleich sind.
Die
array1.equals(array2)
:Vergleichen Sie das Objekt mit einem anderen Objekt und geben Sie nur dann true zurück, wenn die Referenz der beiden Objekte gleich ist wie in der
Object.equals()
quelle
Das
equals()
von Arrays wird von geerbtObject
, sodass es nicht den Inhalt der Arrays betrachtet, sondern nur jedes Array als gleich betrachtet.Die
Arrays.equals()
Methoden haben die Arrays' Inhalte vergleichen. Es gibt Überladungen für alle primitiven Typen, und die für Objekte verwendet die eigenenequals()
Methoden der Objekte .quelle
Hier ist die Ausgabe:
Wenn ich diese Art von Problem sehe, würde ich mich persönlich für
Arrays.equals(array1, array2)
Ihre Frage entscheiden, um Verwirrung zu vermeiden.quelle