JavaRush /Java Blogu /Random-AZ /Java-da hashCode() və equals() metodları ilə işləmək
Lenchik854
Səviyyə
Chernihiv

Java-da hashCode() və equals() metodları ilə işləmək

Qrupda dərc edilmişdir
Bu yazıda metodlar hashCode()equals(). Mən onların standart tətbiqi, eləcə də onları necə düzgün ləğv etmək barədə danışmaq istəyirəm. Mən həmçinin Apache Common paketinin köməkçi siniflərindən istifadə edərək bu metodların həyata keçirilməsi haqqında yazacam. Java-da hashCode() və equals() metodları ilə işləmək - 1Bu yazının məzmunu:
  1. Istifadə hashCode()equals().
  2. Defolt davranışı ləğv edin.
  3. Apache Commons Lang-ı ləğv etmək hashCode()equals()istifadə etmək.
  4. Xatırlamaq vacib olan bir şey.
  5. ORM istifadə edərkən xüsusi diqqət.
hashCode()və metodları java obyektləri üçün ana sinif olan equals()sinifdə müəyyən edilmişdir . ObjectBuna görə də, bütün java obyektləri bu metodlardan standart tətbiqetməni miras alır.

hashCode() və bərabər() istifadə

Metod hashCode()verilmiş obyekt üçün unikal tam ədəd əldə etmək üçün istifadə olunur. Obyektin hash cədvəlində (həmçinin vedrə adlanır) verilənlər strukturu kimi saxlanması lazım olduqda, onun həmin cədvəldəki yerini müəyyən etmək üçün bu nömrə istifadə olunur. Varsayılan olaraq, obyekt üçün metod hashCode()obyektin saxlandığı yaddaş yerinin nömrəsini qaytarır. Metod equals(), adından da göründüyü kimi, sadəcə iki obyektin bərabərliyini yoxlamaq üçün istifadə olunur. Bu metodun standart tətbiqi sadəcə olaraq iki obyektin istinadlarını yoxlayır ki, onların ekvivalent olub-olmadığını yoxlayır.

Defolt davranışı ləğv etmək

Dərslərinizdə bu üsullardan heç birini ləğv etmədiyiniz müddətcə hər şey yaxşı işləyir. Ancaq bəzən proqramlar bəzi obyektlərin standart davranışını dəyişdirməlidir. Bir nümunə götürək Employee. Belə bir sinfin minimum mümkün strukturunu yazaq.
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;
    }
}
Yuxarıda təsvir edilən sinif Employeebəzi əsas atributlara və giriş metodlarına malikdir. İndi sinfin iki obyektini müqayisə etməmiz lazım olan sadə bir vəziyyətə baxaq 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));
    }
}
Yuxarıda yazılan metodun “yanlış” qaytaracağını təxmin etmək üçün bir kəşfiyyatçı lazım deyil. Ancaq bu iki obyektin eyni olduğunu nəzərə alsaq, bu, həqiqətən düzgündürmü? Real vaxt tətbiqində metod doğru qayıtmalıdır. equals()Düzgün davranışa nail olmaq üçün aşağıda edildiyi kimi metodu ləğv etməliyik :
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());
}
Bu metodu sinifinizə əlavə edin Employeevə ekvivalentlik yoxlanışı “doğru”nu qaytaracaq. Bununla belə, biz hər şeyi etdikmi? Hələ yox. Dəyişdirilmiş sinfimizi daha bir şəkildə sınaqdan keçirək.
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);
    }
}
Komanda System.out.println(employee)iki obyekti çap edir. Hər iki obyekt ekvivalent idisə və Setyalnız unikal obyektlər içərisində idisə, onda HashSetiçəridə yalnız bir nümunə olmalıdır, yəni. hər iki obyekt sinfin eyni nümunələrinə istinad edir Employee. Nəyi əldən vermişik? İkinci vacib üsulu qaçırdıq hashCode(). Java sənədlərində deyildiyi kimi, metodu ləğv etsəniz equals(), o zaman metodu ləğv etməlisiniz hashCode(). Beləliklə, sinfimizə başqa bir üsul əlavə edək Employee.
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + getId();
    return result;
 }
Bu metodu bir dəfə sinfimizə əlavə etdik və yalnız bir obyekt çap olunacaq və beləliklə, e1 və e2 ekvivalentliyinin yoxlanılması doğru oldu.

Apache Commons Lang-ı ləğv etmək hashCode()və istifadə etməkequals()

Apache Commons çağırış metodları hashCode()equals(). Aşağıda istifadəni görürük:
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();
    }
 }
Digər tərəfdən, kod redaktorlarından birini istifadə edirsinizsə, onlar da sizin üçün bəzi gözəl strukturları çağıra bilməlidirlər. Məsələn, Eclipse IDE-də sinif >> mənbə > Generating hashCode() və equals() üzərinə sağ klikləsəniz ... bu sizin üçün çox gözəl tətbiq yaradacaq. Java-da hashCode() və equals() metodları ilə işləmək - 2Xatırlamaq vacib olan bir şey.
  1. hashCode()Həmişə həm və həm də çağırmaq üçün eyni obyekt atributlarından istifadə edin equals(). Sadəcə bizim vəziyyətimizdə istifadə etdik employee id.
  2. Metod equals()davamlı olmalıdır (əgər obyekt dəyişməyibsə, metod eyni dəyəri qaytarmalıdır).
  3. Nə vaxtsa a.equals(b), o zaman a.hashCode()eyni olmalıdır b.hashCode().
  4. Bir metodu ləğv etsəniz, ikincisini ləğv etməlisiniz.

ORM istifadə edərkən xüsusi diqqət

Əgər ORM ilə məşğul olursunuzsa (ru.wikipedia.org/wiki/ORM), onda həmişə alıcılardan istifadə edin və heç vaxt sahə istinadlarından istifadə edin hashCode(). equals()Bunun səbəbi, ORM-də vaxtaşırı sahələr tənbəl yüklə yüklənir və onların alıcıları çağırılana qədər əlçatan olmur. Məsələn, bizim sinfimizdə Employeeistifadə edirik e1.id == e2.id. D sahələrinin tənbəl yükləmə ilə yüklənməsi tamamilə mümkündür i. Sahələrdən biri 0 və ya null ola bilər və biz səhv davranış alacağıq. Lakin, istifadə olunarsa e1.getId() == e2.getId(), sahələr tənbəl yükləmə ilə yüklənsə belə əmin ola bilərik; alıcıya zəng etmək ilk olaraq sahəni dolduracaq. hashCode()və üsulları haqqında bildiyim hər şey budur equals(). Ümid edirəm ki, bu, bir yerdə kiməsə kömək edir. Təhsilinizdə uğurlar!! ps Bu mənim ilk tərcümə cəhdimdir. Hər şeyi müəllifin demək istədiyinə mümkün qədər yaxın çatdırmağa çalışdım. Hər hansı bir şərhiniz varsa, şərhlərdə yazın. Ciddi mühakimə etməyin :-))) Orijinal məqalə
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION