JavaRush /Java Blog /Random-ID /Bekerja dengan metode hashCode() dan equal() di Java
Lenchik854
Level 0
Chernihiv

Bekerja dengan metode hashCode() dan equal() di Java

Dipublikasikan di grup Random-ID
Dalam posting ini saya akan menguraikan pemahaman saya tentang 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. Bekerja dengan metode hashCode() dan equal() di Java - 1Isi postingan ini:
  1. Menggunakan hashCode()dan equals().
  2. Ganti perilaku default.
  3. Mengganti hashCode()dan equals()menggunakan Apache Commons Lang.
  4. Sesuatu yang penting untuk diingat.
  5. Perhatian Khusus Saat Menggunakan ORM.
Metode 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 ini hashCode()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 file Employee. 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 Employeememiliki 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 Employeedan 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 Sethanya objek unik yang dikandungnya, maka HashSetseharusnya 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. Bekerja dengan metode hashCode() dan equal() di Java - 2Sesuatu yang penting untuk diingat.
  1. Selalu gunakan atribut objek yang sama untuk memanggil and hashCode()dan equals(). Dalam kasus kami, kami menggunakan employee id.
  2. Metode equals()harus tetap (jika objek tidak berubah, metode harus mengembalikan nilai yang sama).
  3. Kapanpun a.equals(b), maka a.hashCode()harus sama dengan b.hashCode().
  4. 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 references hashCode(). 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 ibidang 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
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION