JavaRush /Java blogi /Random-UZ /Java'da hashCode() va equals() usullari bilan ishlash
Lenchik854
Daraja
Chernihiv

Java'da hashCode() va equals() usullari bilan ishlash

Guruhda nashr etilgan
Ushbu postda men usullar hashCode()va equals(). Men ularning sukut bo'yicha amalga oshirilishi, shuningdek, ularni qanday qilib to'g'ri bekor qilish haqida gapirmoqchiman. Men Apache Common paketining yordamchi sinflari yordamida ushbu usullarni amalga oshirish haqida ham yozaman. Java-da hashCode() va equals() usullari bilan ishlash - 1Ushbu postning mazmuni:
  1. Foydalanish hashCode()va equals().
  2. Standart xatti-harakatni bekor qilish.
  3. Apache Commons Lang- ni bekor qilish hashCode()va equals()ishlatish.
  4. Esda tutish muhim bo'lgan narsa.
  5. ORM dan foydalanishda alohida e'tibor.
hashCode()va usullari java ob'ektlari uchun asosiy sinf bo'lgan equals()sinfda aniqlangan . ObjectShuning uchun barcha java ob'ektlari ushbu usullardan standart amalga oshirishni meros qilib oladi.

hashCode() va teng() dan foydalanish

Usul hashCode()berilgan ob'ekt uchun yagona butun sonni olish uchun ishlatiladi. Ob'ektni xesh-jadvalda (shuningdek chelak deb ham ataladi) ma'lumotlar strukturasi sifatida saqlash kerak bo'lganda, bu raqam uning ushbu jadvaldagi o'rnini aniqlash uchun ishlatiladi. Odatiy bo'lib, ob'ekt uchun usul hashCode()ob'ekt saqlanadigan xotira joyining raqamini qaytaradi. Usul equals(), nomidan ko'rinib turibdiki, ikkita ob'ektning tengligini tekshirish uchun ishlatiladi. Ushbu usulning sukut bo'yicha amalga oshirilishi shunchaki ikkita ob'ektning havolalarini ularning ekvivalentligini tekshirish uchun tekshiradi.

Standart xatti-harakatni bekor qilish

Darslaringizda ushbu usullardan hech birini bekor qilmasangiz, hamma narsa yaxshi ishlaydi. Ammo ba'zida ilovalar ba'zi ob'ektlarning standart xatti-harakatlarini o'zgartirishi kerak. Keling, sizda mavjud bo'lgan misolni olaylik Employee. Keling, bunday sinfning mumkin bo'lgan minimal tuzilishini yozamiz.
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;
    }
}
Yuqorida tavsiflangan sinfda Employeeba'zi bir asosiy atributlar va yordamchi usullar mavjud. Keling, sinfning ikkita ob'ektini taqqoslashimiz kerak bo'lgan oddiy vaziyatni ko'rib chiqaylik 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));
    }
}
Yuqoridagi usul "noto'g'ri" ni qaytarishini taxmin qilish uchun bashoratli odam kerak emas. Ammo bu ikki ob'ekt bir xil ekanligini hisobga olsak, bu haqiqatan ham to'g'rimi? Haqiqiy vaqtda dasturda usul haqiqatni qaytarishi kerak. equals()To'g'ri xatti-harakatga erishish uchun biz quyida bo'lgani kabi usulni bekor qilishimiz kerak :
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());
}
Ushbu usulni sinfingizga qo'shing Employeeva ekvivalentlik tekshiruvi "to'g'ri" ni qaytaradi. Biroq, biz hamma narsani qildikmi? Hali emas. Keling, o'zgartirilgan sinfimizni yana bir usulda sinab ko'raylik.
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);
    }
}
Buyruq System.out.println(employee)ikkita ob'ektni chop etadi. Agar ikkala ob'ekt ekvivalent bo'lsa va Setunda faqat noyob ob'ektlar mavjud bo'lsa, unda HashSetfaqat bitta misol bo'lishi kerak, ya'ni. ikkala ob'ekt ham sinfning bir xil misollariga ishora qiladi Employee. Biz nimani o'tkazib yubordik? Biz ikkinchi muhim usulni o'tkazib yubordik hashCode(). Java hujjatlarida aytilganidek, agar siz usulni bekor qilsangiz equals(), u holda siz usulni bekor qilishingiz kerak bo'ladi hashCode(). Shunday qilib, keling, sinfimizga yana bir usul qo'shamiz Employee.
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + getId();
    return result;
 }
Biz ushbu usulni sinfimizga bir marta qo'shdik va faqat bitta ob'ekt chop etiladi va shuning uchun e1 va e2 ning ekvivalentligini tekshirish haqiqatni ko'rsatdi.

Apache Commons Lang- ni bekor qilish hashCode()va ishlatishequals()

Apache Commons qo'ng'iroq usullari uchun ikkita ajoyib yordamchi sinfni taqdim etadi hashCode()va equals(). Quyida biz foydalanishni ko'ramiz:
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();
    }
 }
Boshqa tomondan, agar siz kod muharrirlaridan birini ishlatsangiz, ular siz uchun yaxshi tuzilmalarni chaqira olishlari kerak. Misol uchun, agar Eclipse IDE da siz >> manba > Generating hashCode() va equals() ni sichqonchaning o'ng tugmachasini bossangiz ... bu siz uchun juda yaxshi dastur yaratadi. Java-da hashCode() va equals() usullari bilan ishlash - 2Esda tutish muhim bo'lgan narsa.
  1. hashCode()Ikkala va va ni chaqirish uchun har doim bir xil ob'ekt atributlaridan foydalaning equals(). Faqat bizning holatlarimizda biz foydalanganmiz employee id.
  2. Usul equals()doimiy bo'lishi kerak (agar ob'ekt o'zgarmagan bo'lsa, usul bir xil qiymatni qaytarishi kerak).
  3. Qachon bo'lsa a.equals(b), keyin a.hashCode()bir xil bo'lishi kerak b.hashCode().
  4. Agar siz bitta usulni bekor qilsangiz, ikkinchisini bekor qilishingiz kerak.

ORM dan foydalanishda alohida e'tibor

Agar siz ORM (ru.wikipedia.org/wiki/ORM) bilan ishlayotgan bo'lsangiz, har doim qabul qiluvchilardan foydalaning va hech qachon maydon havolalaridan foydalanmang hashCode(). equals()Buning sababi, ORMda vaqti-vaqti bilan maydonlar dangasa yuk yordamida yuklanadi va ularning qabul qiluvchilari chaqirilmaguncha ularga kirish imkoni bo'lmaydi. Masalan, sinfimizda Employeebiz dan foydalanamiz e1.id == e2.id. D maydonlari dangasa yuklash yordamida yuklangan bo'lishi mumkin i. Maydonlardan biri 0 yoki null bo'lishi mumkin va biz noto'g'ri xatti-harakatlarga ega bo'lamiz. Ammo, agar ishlatilsa e1.getId() == e2.getId(), biz dangasa yuklash yordamida maydonlar yuklangan bo'lsa ham ishonch hosil qilishimiz mumkin; oluvchini chaqirish birinchi navbatda maydonni to'ldiradi. Bu hashCode()va usullari haqida men bilgan hamma narsa equals(). Umid qilamanki, bu biror joyda kimgadir yordam beradi. O'qishlaringizga omad!! ps Bu mening tarjimaga birinchi urinishim. Men hamma narsani iloji boricha muallif aytmoqchi bo'lgan narsaga yaqinroq etkazishga harakat qildim. Agar sizda biron bir fikr bo'lsa, iltimos, sharhlarda yozing. Qattiq hukm qilmang :-))) Original maqola
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION