Saya mencoba untuk mengganti metode sama di Jawa. Saya memiliki kelas People
yang pada dasarnya memiliki 2 bidang data name
dan age
. Sekarang saya ingin menimpaequals
metode sehingga saya dapat memeriksa antara 2 objek Orang.
Kode saya adalah sebagai berikut
public boolean equals(People other){
boolean result;
if((other == null) || (getClass() != other.getClass())){
result = false;
} // end if
else{
People otherPeople = (People)other;
result = name.equals(other.name) && age.equals(other.age);
} // end else
return result;
} // end equals
Tapi saat saya menulis age.equals(other.age)
itu memberi saya kesalahan karena metode yang sama hanya dapat membandingkan String dan usia adalah Integer.
Larutan
Saya menggunakan ==
operator seperti yang disarankan dan masalah saya terpecahkan.
java
overriding
equals
berang-berang
sumber
sumber
Jawaban:
Keluaran:
sumber
hash = 53 * hash
mengapa kamu menggunakan itu?getClass()
akan menyebabkan masalah jika kelas tersebut mendapat subkelas, dan dibandingkan dengan objek kelas super.hashCode()
instanceof
operator atauisAssignableFrom
. Ini akan membutuhkan pencocokan jenis tepat, bukan pencocokan subjenis. - Persyaratan simetris. Juga untuk membandingkanString
atau tipe Objek lainnya, Anda dapat menggunakanObjects.equals(this.name,other.name)
.Memperkenalkan tanda tangan metode baru yang mengubah jenis parameter disebut overloading :
Ini
People
berbeda denganObject
.Ketika tanda tangan metode tetap sama dengan superclassnya, itu disebut overriding dan
@Override
anotasi membantu membedakan keduanya pada waktu kompilasi:Tanpa melihat pernyataan sebenarnya dari
age
, sulit untuk mengatakan mengapa kesalahan itu muncul.sumber
Saya tidak yakin dengan detailnya karena Anda belum memposting seluruh kode, tetapi:
hashCode()
jugaequals
metode harus memilikiObject
, tidakPeople
sebagai jenis argumen. Saat ini Anda membebani, tidak menimpa, metode sama, yang mungkin bukan yang Anda inginkan, terutama mengingat Anda memeriksa tipenya nanti.instanceof
untuk memeriksa apakah itu adalah objek Orang misalnyaif (!(other instanceof People)) { result = false;}
equals
digunakan untuk semua objek, tapi tidak primitif. Saya pikir maksud Anda usia adalahint
(primitif), dalam hal ini gunakan saja==
. Perhatikan bahwa Integer (dengan huruf besar 'I') adalah Objek yang harus dibandingkan dengan sama.Lihat Masalah apa yang harus dipertimbangkan saat mengganti sama dengan dan kode hash di Java? untuk lebih jelasnya.
sumber
sumber
Butir 10: Patuhi kontrak umum saat mengganti yang sama
Setiap instance kelas secara inheren unik . Ini berlaku untuk kelas seperti Thread yang mewakili entitas aktif daripada nilai. Implementasi sama yang disediakan oleh Object memiliki perilaku yang tepat untuk kelas-kelas ini.
Kelas tidak perlu memberikan pengujian "persamaan logis". Misalnya, java.util.regex.Pattern dapat diganti sama dengan untuk memeriksa apakah dua contoh Pola mewakili ekspresi reguler yang persis sama, tetapi perancang tidak berpikir bahwa klien akan membutuhkan atau menginginkan fungsionalitas ini. Dalam keadaan ini, implementasi yang sama yang diwarisi dari Object sangat ideal.
Superkelas telah menimpa sama, dan perilaku kelas super sesuai untuk kelas ini. Misalnya, sebagian besar implementasi Set mewarisi implementasi yang sama dari AbstractSet, implementasi List dari AbstractList, dan implementasi Map dari AbstractMap.
Kelas ini privat atau paket-privat , dan Anda yakin bahwa metode yang sama tidak akan pernah dipanggil. Jika Anda sangat menghindari risiko, Anda dapat mengganti metode sama dengan untuk memastikannya tidak dipanggil secara tidak sengaja:
The
equals
Metode mengimplementasikan relasi ekivalen. Ini memiliki properti ini:Refleksif: Untuk nilai referensi bukan nol
x
,x.equals(x)
harus mengembalikan true.Symmetric: Untuk nilai referensi bukan null
x
dany
,x.equals(y)
harus mengembalikan true jika dan hanya jika y.equals (x) mengembalikan true.Transitif: Untuk setiap nilai referensi non-null
x
,y
,z
, jikax.equals(y)
kembalitrue
dany.equals(z)
kembalitrue
, makax.equals(z)
harus kembalitrue
.Konsisten: Untuk nilai referensi bukan nol
x
dany
, beberapa pemanggilanx.equals(y)
harus secara konsisten mengembalikantrue
atau kembali secara konsistenfalse
, asalkan tidak ada informasi yang digunakan dalam perbandingan yang sama yang dimodifikasi.Untuk nilai referensi bukan nol
x
,x.equals(null)
harus dikembalikanfalse
.Berikut resep untuk metode sama berkualitas tinggi:
Gunakan
==
operator untuk memeriksa apakah argumennya adalah referensi ke objek ini. Jika demikian, kembalikan true. Ini hanyalah pengoptimalan kinerja tetapi layak dilakukan jika perbandingannya berpotensi mahal.Gunakan
instanceof
operator untuk memeriksa apakah argumen memiliki tipe yang benar. Jika tidak, kembalikan false. Biasanya, tipe yang benar adalah kelas tempat metode tersebut terjadi. Terkadang, ini adalah beberapa antarmuka yang diimplementasikan oleh kelas ini. Gunakan antarmuka jika kelas mengimplementasikan antarmuka yang menyempurnakan kontrak yang sama untuk mengizinkan perbandingan antar kelas yang mengimplementasikan antarmuka. Antarmuka koleksi seperti Set, List, Map, dan Map.Entry memiliki properti ini.Keluarkan argumen ke tipe yang benar. Karena pemeran ini didahului dengan contoh pengujian, maka dijamin berhasil.
Untuk setiap bidang "signifikan" di kelas, periksa apakah bidang argumen tersebut cocok dengan bidang terkait dari objek ini. Jika semua tes ini berhasil, kembalikan nilai true; jika tidak, kembalikan false. Jika tipe di Langkah 2 adalah antarmuka, Anda harus mengakses kolom argumen melalui metode antarmuka; jika tipenya adalah kelas, Anda mungkin dapat mengakses bidang secara langsung, bergantung pada aksesibilitasnya.
Untuk bidang primitif yang tipenya bukan
float
ataudouble
, gunakan==
operator untuk perbandingan; untuk bidang referensi objek, panggilequals
metode secara rekursif; untukfloat
bidang, gunakanFloat.compare(float, float)
metode statis ; dan untukdouble
ladang, gunakanDouble.compare(double, double)
. Perlakuan khusus bidang apung dan ganda diperlukan oleh keberadaanFloat.NaN
,-0.0f
dan nilai ganda analog; Meskipun Anda dapat membandingkanfloat
dandouble
kolom dengan metode statisFloat.equals
danDouble.equals
, ini akan memerlukan autoboxing pada setiap perbandingan, yang akan memiliki kinerja yang buruk. Untukarray
bidang, terapkan pedoman ini ke setiap elemen. Jika setiap elemen dalam kolom array signifikan, gunakan salah satuArrays.equals
metode.Beberapa bidang referensi objek mungkin berisi secara sah
null
. Untuk menghindari kemungkinan aNullPointerException
, periksa bidang tersebut untuk persamaan menggunakan metode statisObjects.equals(Object, Object)
.sumber
hashCode()
. Juga catatan, bahwa sejak Java7 menulisequals()
danhashCode()
metode telah menjadi jauh lebih mudah dengan menggunakanObjects.equals()
,Arrays.equals()
danObjects.hashCode()
,Arrays.hashCode()
.if (getClass() != obj.getClass()) ...
daripada menggunakan operator instanceof. Ini akan membutuhkan pencocokan jenis tepat , bukan pencocokan subjenis. - Persyaratan simetris.Karena saya menebak
age
adalah tipeint
:sumber
NullPointerException
jikaname
adalahnull
.name
tidak pernah diberinull
nilai ...Saat membandingkan objek di Java, Anda melakukan pemeriksaan semantik , membandingkan tipe dan status identifikasi objek ke:
null
Aturan:
a.equals(b) == b.equals(a)
equals()
selalu menghasilkantrue
ataufalse
, tapi tidak pernahNullpointerException
,ClassCastException
atau lemparan lainnyaPerbandingan:
instanceof
untuk perbandingan tipe (yang hanya berfungsi selama tidak ada subkelas, dan melanggar aturan simetri ketikaA extends B -> a instanceof b != b instanceof a)
.Untuk
Person
kelas Anda :Kelas utilitas umum yang dapat digunakan kembali:
Untuk
Person
kelas Anda , menggunakan kelas utilitas ini:sumber
jika age int Anda harus menggunakan == jika itu adalah objek Integer maka Anda dapat menggunakan equals (). Anda juga perlu menerapkan metode kode hash jika Anda mengganti sama. Rincian kontrak tersedia di javadoc Object dan juga di berbagai halaman web.
sumber
Inilah solusi yang baru-baru ini saya gunakan:
sumber