Dalam posting ini saya akan menguraikan pemahaman saya tentang metode Mengganti
Apache Commons menyediakan dua kelas pembantu yang hebat untuk memanggil metode
hashCode()
dan equals()
. Saya ingin berbicara tentang penerapan defaultnya, serta cara menggantinya dengan benar. Saya juga akan menulis tentang penerapan metode ini menggunakan kelas pembantu paket Apache Common. Isi postingan ini:
- Menggunakan
hashCode()
danequals()
. - Ganti perilaku default.
- Mengganti
hashCode()
danequals()
menggunakan Apache Commons Lang. - Sesuatu yang penting untuk diingat.
- Perhatian Khusus Saat Menggunakan ORM.
hashCode()
and equals()
didefinisikan di kelas Object
, yang merupakan kelas induk untuk objek Java. Oleh karena itu, semua objek java mewarisi implementasi default dari metode ini.
Menggunakan kode hash() dan sama dengan()
Metode inihashCode()
digunakan untuk mendapatkan bilangan bulat unik untuk suatu objek tertentu. Ketika suatu objek perlu disimpan sebagai struktur data dalam tabel hash (juga disebut bucket), nomor ini digunakan untuk menentukan lokasinya di tabel tersebut. Secara default, metode hashCode()
untuk suatu objek mengembalikan nomor lokasi memori tempat objek disimpan. Metode ini equals()
, seperti namanya, digunakan untuk sekadar memeriksa kesetaraan dua objek. Implementasi default dari metode ini hanya memeriksa referensi dari dua objek untuk melihat apakah keduanya setara.
Mengganti perilaku default
Semuanya berfungsi dengan baik selama Anda tidak mengganti salah satu metode ini di kelas Anda. Namun terkadang aplikasi perlu mengubah perilaku default beberapa objek. Mari kita ambil contoh di mana Anda memiliki fileEmployee
. Mari kita tuliskan struktur minimum yang mungkin dari kelas tersebut.
public class Employee
{
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
Kelas yang dijelaskan di atas Employee
memiliki beberapa atribut dasar dan metode pengakses. Sekarang mari kita lihat situasi sederhana di mana kita perlu membandingkan dua objek kelas Employee
.
public class EqualsTest {
public static void main(String[] args) {
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.setId(100);
e2.setId(100);
//Печатает false в консоли
System.out.println(e1.equals(e2));
}
}
Tidak perlu seorang peramal untuk menebak bahwa cara di atas akan menghasilkan hasil yang “salah”. Tapi apakah ini benar, mengingat kedua benda ini sama? Dalam penerapan waktu nyata, metode harus mengembalikan nilai true. Untuk mencapai perilaku yang benar, kita perlu mengganti metode ini equals()
, seperti yang dilakukan di bawah ini:
public boolean equals(Object o) {
if(o == null)
{
return false;
}
if (o == this)
{
return true;
}
if (getClass() != o.getClass())
{
return false;
}
Employee e = (Employee) o;
return (this.getId() == e.getId());
}
Tambahkan metode ini ke kelas Anda Employee
dan pemeriksaan kesetaraan akan mengembalikan "benar". Namun, apakah kita sudah melakukan semuanya? Belum. Mari kita uji kelas kita yang telah dimodifikasi dengan satu cara lagi.
import java.util.HashSet;
import java.util.Set;
public class EqualsTest
{
public static void main(String[] args)
{
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.setId(100);
e2.setId(100);
//Печатает 'true'
System.out.println(e1.equals(e2));
Set employees = new HashSet();
employees.add(e1);
employees.add(e2);
//Печатает два an object
System.out.println(employees);
}
}
Perintah System.out.println(employee)
mencetak dua objek. Jika kedua objek setara, dan Set
hanya objek unik yang dikandungnya, maka HashSet
seharusnya hanya ada satu instance di dalamnya, yaitu. kedua objek merujuk pada instance kelas yang sama Employee
. Apa yang kita lewatkan? Kami melewatkan metode penting kedua hashCode()
. Seperti yang dikatakan dalam dokumentasi java, jika Anda mengganti metode tersebut equals()
, maka Anda diharuskan untuk mengganti metode tersebut hashCode()
. Jadi mari tambahkan metode lain ke kelas kita Employee
.
@Override
public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + getId();
return result;
}
Kami menambahkan metode ini satu kali ke kelas kami, dan hanya satu objek yang akan dicetak, dan dengan demikian, pemeriksaan kesetaraan e1 dan e2 menunjukkan kebenarannya.
Mengganti hashCode()
dan equals()
menggunakan Apache Commons Lang
Apache Commons menyediakan dua kelas pembantu yang hebat untuk memanggil metode hashCode()
dan equals()
. Di bawah ini kita melihat penggunaannya:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Employee
{
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
@Override
public int hashCode()
{
final int PRIME = 31;
return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).
toHashCode();
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (o.getClass() != getClass())
return false;
Employee e = (Employee) o;
return new EqualsBuilder().
append(getId(), e.getId()).
isEquals();
}
}
Di sisi lain, jika Anda menggunakan salah satu editor kode, mereka juga dapat memanggil beberapa struktur yang bagus untuk Anda. Misalnya, jika di IDE Eclipse Anda mengklik kanan pada kelas >> sumber > Menghasilkan kode hash() dan sama dengan() ... itu akan menghasilkan implementasi yang sangat bagus untuk Anda. Sesuatu yang penting untuk diingat.
- Selalu gunakan atribut objek yang sama untuk memanggil and
hashCode()
danequals()
. Dalam kasus kami, kami menggunakanemployee id
. - Metode
equals()
harus tetap (jika objek tidak berubah, metode harus mengembalikan nilai yang sama). - Kapanpun
a.equals(b)
, makaa.hashCode()
harus sama denganb.hashCode()
. - Jika Anda mengganti satu metode, Anda harus mengganti metode kedua.
Perhatian Khusus Saat Menggunakan ORM
Jika Anda berurusan dengan ORM (ru.wikipedia.org/wiki/ORM), selalu gunakan getter dan jangan pernah menggunakan field referenceshashCode()
. equals()
Hal ini karena dalam ORM, dari waktu ke waktu field dimuat menggunakan pemuatan lambat dan tidak dapat diakses sampai pengambilnya dipanggil. Misalnya, di kelas kami Employee
, kami menggunakan e1.id == e2.id
. Sangat mungkin bahwa i
bidang d dimuat menggunakan pemuatan lambat. Salah satu bidang mungkin 0 atau nol dan kita akan mendapatkan perilaku yang salah. Namun, jika , digunakan e1.getId() == e2.getId()
, kita dapat yakin meskipun kolom tersebut dimuat menggunakan pemuatan lambat; memanggil pengambil akan mengisi kolom terlebih dahulu. Hanya itu yang saya tahu tentang hashCode()
dan metodenya equals()
. Semoga ini bisa membantu seseorang di suatu tempat. Semoga sukses dengan studimu!! ps Ini adalah upaya terjemahan pertama saya. Saya berusaha menyampaikan semuanya sedekat mungkin dengan apa yang ingin disampaikan penulis. Jika Anda memiliki komentar, silakan tulis di komentar. Jangan menilai secara ketat :-))) Artikel asli
GO TO FULL VERSION