Catatan yang Arrays.equals()tidak berfungsi seperti yang diharapkan untuk array multidimensi, itu hanya membandingkan item dari dimensi 1 untuk persamaan referensi. Apache commons ArrayUtils.isEqualsbekerja dengan array multidimensi.
Adam Parkin
4
Saya terpana. Apakah ada alasan untuk array.equals diimplementasikan untuk perbandingan pointer daripada membandingkan panjang dan setiap objek?
Danau
2
@Lake is tidak membandingkan panjang array dan objek yang terkandung, tetapi apa yang tidak dilakukannya adalah perbandingan yang mendalam. Faktanya sama tidak bekerja seperti yang diharapkan untuk array rusak, ini seharusnya tidak menjadi masalah di tempat pertama.
@JeewanthaSamaraweera itu adalah definisi untuk metode itu, namun untuk .equalsitu tidak membandingkan konten yang mengapa Anda memerlukan metode itu.
Peter Lawrey
86
Ini masalah yang terkenal: .equals()karena array rusak parah, tapi jangan pernah menggunakannya.
Yang mengatakan, itu tidak "rusak" seperti pada "seseorang telah melakukannya dengan cara yang benar-benar salah" - itu hanya melakukan apa yang didefinisikan dan bukan apa yang biasanya diharapkan. Jadi untuk para puritan: tidak apa-apa, dan itu juga berarti, jangan pernah menggunakannya.
Sekarang perilaku yang diharapkan equalsadalah membandingkan data. Perilaku default adalah membandingkan identitas, karena Objecttidak memiliki data (untuk puritan: ya, tapi bukan itu intinya); Asumsinya adalah, jika Anda perluequals dalam subkelas, Anda akan menerapkannya. Dalam array, tidak ada implementasi untuk Anda, jadi Anda tidak seharusnya menggunakannya.
Jadi perbedaannya adalah, Arrays.equals(array1, array2)berfungsi seperti yang Anda harapkan (yaitu membandingkan konten), array1.equals(array2)kembali ke Object.equalsimplementasi, yang pada gilirannya membandingkan identitas, dan dengan demikian lebih baik digantikan oleh ==(untuk pembuat puritan: ya saya tahu tentang null).
Masalahnya, bahkan Arrays.equals(array1, array2)akan menggigit Anda dengan keras jika elemen array tidak diimplementasikan equalsdengan benar. Itu adalah pernyataan yang sangat naif, saya tahu, tetapi ada kasus yang sangat kurang penting: pertimbangkan array 2D.
Array 2D di Java adalah array array, dan array equalsrusak (atau tidak berguna jika Anda mau), jadi Arrays.equals(array1, array2)tidak akan berfungsi seperti yang Anda harapkan pada array 2D.
Apakah array memiliki implementasi kustom equals()? Saya pikir tidak diganti dari Object.
Martijn Courteaux
@MichaelBorgwardt itu adalah perpustakaan sistem, dengan metode yang tidak melakukan apa yang dikatakan di javadoc. Kedengarannya cukup rusak bagiku. Yang mengatakan, saya akui itu adalah pernyataan yang sangat bisa diperdebatkan, tetapi saya percaya bahwa "itu rusak" diingat lebih baik, dan dengan demikian jauh lebih mudah untuk memikirkannya dengan cara ini.
alf
@ MartijnCourteaux itulah masalahnya :)
alf
3
Untuk array array, Anda perlu Arrays.deepEquals--- itulah yang someArray.equalsseharusnya dilakukan selama ini. (Terkait:. Objects.deepEquals)
Kevin J. Chase
16
Lihat ke dalam implementasi dua metode untuk memahami mereka secara mendalam:
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);}
sementara:
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;}
Mendesah. Kembali di 70-an saya adalah "programmer sistem" (sysadmin) untuk sistem IBM 370, dan majikan saya adalah anggota kelompok pengguna IBM SHARE. Kadang-kadang akan terjadi bahwa seseorang menyerahkan APAR (laporan bug) pada beberapa perilaku tak terduga dari beberapa perintah CMS, dan IBM akan menanggapi NOTABUG: perintah melakukan apa yang dirancang untuk dilakukan (dan apa yang dikatakan dokumentasi).
SHARE datang dengan penghitung untuk ini: BAD - Broken Asesign. Saya pikir ini mungkin berlaku untuk implementasi equals for array ini.
Tidak ada yang salah dengan implementasi Object.equals. Objek tidak memiliki data anggota, jadi tidak ada yang bisa dibandingkan. Dua "Objek" adalah sama jika dan hanya jika mereka, pada kenyataannya, adalah Obyek yang sama (secara internal, alamat dan panjang yang sama).
Tetapi logika itu tidak berlaku untuk array. Array memiliki data, dan Anda mengharapkan perbandingan (melalui sama dengan) untuk membandingkan data. Idealnya, cara Array.deepEquals lakukan, tapi setidaknya cara Array.equals lakukan (perbandingan elemen yang dangkal).
Jadi masalahnya adalah array (sebagai objek bawaan) tidak menimpa Object.equals. String (sebagai kelas bernama) tidak menimpa Object.equals dan memberikan hasil yang Anda harapkan.
Jawaban lain yang diberikan adalah benar: [...]. Equals ([....]) cukup membandingkan pointer dan bukan isinya. Mungkin suatu hari seseorang akan memperbaiki ini. Atau mungkin tidak: berapa banyak program yang ada akan rusak jika [...] sama dengan benar-benar membandingkan elemen? Tidak banyak, saya kira, tetapi lebih dari nol.
The equals()array diwariskan dari Object, sehingga tidak melihat isi dari arrrays, hanya menganggap setiap array sama untuk dirinya sendiri.
The Arrays.equals()metode yang membandingkan isi array. Ada kelebihan untuk semua tipe primitif, dan satu untuk objek menggunakan metode objek sendiri equals().
Anda mengatakan "isi array", apakah ini berarti array multidimensi juga?
AlanFoster
@AlanFoster: tidak. Array multidimensi adalah array array, yang berarti mereka memilah Array.equals (Object [], Object []) akan dipanggil, yang memanggil metode equals () equals sub-array
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));}}
Berikut hasilnya:
array1 and array2 equal:false
array1 and array2 equal:false
array1 and array3 equal:true
array1 and array3 equal:false
Melihat masalah seperti ini saya pribadi akan mencari Arrays.equals(array1, array2)sesuai pertanyaan Anda untuk menghindari kebingungan.
Tampaknya benar tetapi pada array, urutan elemen juga penting. Misalnya, jika Anda ada Objek array lain [] array4 = Objek baru [] {123, 1}; dengan Arrays.equals (array3, array4), itu akan mengembalikan false.
Jawaban:
array1.equals(array2)
sama denganarray1 == array2
, yaitu apakah array yang sama. Seperti ditunjukkan @alf, bukan itu yang diharapkan kebanyakan orang.Arrays.equals(array1, array2)
membandingkan isi dari array.Demikian pula
array.toString()
mungkin tidak terlalu berguna dan perlu Anda gunakanArrays.toString(array)
.sumber
Arrays.equals()
tidak berfungsi seperti yang diharapkan untuk array multidimensi, itu hanya membandingkan item dari dimensi 1 untuk persamaan referensi. Apache commonsArrayUtils.isEquals
bekerja dengan array multidimensi.Arrays.deepEquals(Object[], Object[])
..equals
itu tidak membandingkan konten yang mengapa Anda memerlukan metode itu.Ini masalah yang terkenal:
.equals()
karena array rusak parah, tapi jangan pernah menggunakannya.Yang mengatakan, itu tidak "rusak" seperti pada "seseorang telah melakukannya dengan cara yang benar-benar salah" - itu hanya melakukan apa yang didefinisikan dan bukan apa yang biasanya diharapkan. Jadi untuk para puritan: tidak apa-apa, dan itu juga berarti, jangan pernah menggunakannya.
Sekarang perilaku yang diharapkan
equals
adalah membandingkan data. Perilaku default adalah membandingkan identitas, karenaObject
tidak memiliki data (untuk puritan: ya, tapi bukan itu intinya); Asumsinya adalah, jika Anda perluequals
dalam subkelas, Anda akan menerapkannya. Dalam array, tidak ada implementasi untuk Anda, jadi Anda tidak seharusnya menggunakannya.Jadi perbedaannya adalah,
Arrays.equals(array1, array2)
berfungsi seperti yang Anda harapkan (yaitu membandingkan konten),array1.equals(array2)
kembali keObject.equals
implementasi, yang pada gilirannya membandingkan identitas, dan dengan demikian lebih baik digantikan oleh==
(untuk pembuat puritan: ya saya tahu tentangnull
).Masalahnya, bahkan
Arrays.equals(array1, array2)
akan menggigit Anda dengan keras jika elemen array tidak diimplementasikanequals
dengan benar. Itu adalah pernyataan yang sangat naif, saya tahu, tetapi ada kasus yang sangat kurang penting: pertimbangkan array 2D.Array 2D di Java adalah array array, dan array
equals
rusak (atau tidak berguna jika Anda mau), jadiArrays.equals(array1, array2)
tidak akan berfungsi seperti yang Anda harapkan pada array 2D.Semoga itu bisa membantu.
sumber
equals()
? Saya pikir tidak diganti dari Object.Arrays.deepEquals
--- itulah yangsomeArray.equals
seharusnya dilakukan selama ini. (Terkait:.Objects.deepEquals
)Lihat ke dalam implementasi dua metode untuk memahami mereka secara mendalam:
sementara:
sumber
Mendesah. Kembali di 70-an saya adalah "programmer sistem" (sysadmin) untuk sistem IBM 370, dan majikan saya adalah anggota kelompok pengguna IBM SHARE. Kadang-kadang akan terjadi bahwa seseorang menyerahkan APAR (laporan bug) pada beberapa perilaku tak terduga dari beberapa perintah CMS, dan IBM akan menanggapi NOTABUG: perintah melakukan apa yang dirancang untuk dilakukan (dan apa yang dikatakan dokumentasi).
SHARE datang dengan penghitung untuk ini: BAD - Broken Asesign. Saya pikir ini mungkin berlaku untuk implementasi equals for array ini.
Tidak ada yang salah dengan implementasi Object.equals. Objek tidak memiliki data anggota, jadi tidak ada yang bisa dibandingkan. Dua "Objek" adalah sama jika dan hanya jika mereka, pada kenyataannya, adalah Obyek yang sama (secara internal, alamat dan panjang yang sama).
Tetapi logika itu tidak berlaku untuk array. Array memiliki data, dan Anda mengharapkan perbandingan (melalui sama dengan) untuk membandingkan data. Idealnya, cara Array.deepEquals lakukan, tapi setidaknya cara Array.equals lakukan (perbandingan elemen yang dangkal).
Jadi masalahnya adalah array (sebagai objek bawaan) tidak menimpa Object.equals. String (sebagai kelas bernama) tidak menimpa Object.equals dan memberikan hasil yang Anda harapkan.
Jawaban lain yang diberikan adalah benar: [...]. Equals ([....]) cukup membandingkan pointer dan bukan isinya. Mungkin suatu hari seseorang akan memperbaiki ini. Atau mungkin tidak: berapa banyak program yang ada akan rusak jika [...] sama dengan benar-benar membandingkan elemen? Tidak banyak, saya kira, tetapi lebih dari nol.
sumber
Array mewarisi
equals()
dariObject
dan karenanya membandingkan hanya mengembalikan true jika membandingkan array terhadap dirinya sendiri.Di sisi lain,
Arrays.equals
bandingkan elemen dari array.Cuplikan ini menjelaskan perbedaannya:
Lihat juga
Arrays.equals()
. Metode lain statis ada juga mungkin menarik:Arrays.deepEquals()
.sumber
The
Arrays.equals(array1, array2)
:periksa apakah kedua array berisi jumlah elemen yang sama, dan semua pasangan elemen yang sesuai dalam kedua array sama.
The
array1.equals(array2)
:membandingkan objek ke objek lain dan mengembalikan true hanya jika referensi kedua objek sama seperti di
Object.equals()
sumber
The
equals()
array diwariskan dariObject
, sehingga tidak melihat isi dari arrrays, hanya menganggap setiap array sama untuk dirinya sendiri.The
Arrays.equals()
metode yang membandingkan isi array. Ada kelebihan untuk semua tipe primitif, dan satu untuk objek menggunakan metode objek sendiriequals()
.sumber
Berikut hasilnya:
Melihat masalah seperti ini saya pribadi akan mencari
Arrays.equals(array1, array2)
sesuai pertanyaan Anda untuk menghindari kebingungan.sumber