JavaRush /Java блогы /Random-KK /Java тіліндегі hashCode() және equals() әдістерімен жұмыс...
Lenchik854
Деңгей
Chernihiv

Java тіліндегі hashCode() және equals() әдістерімен жұмыс істеу

Топта жарияланған
Бұл мақалада мен әдістер туралы түсінігімді hashCode()және equals(). Мен олардың әдепкі орындалуы туралы, сондай-ақ оларды қалай дұрыс қайта анықтау керектігі туралы айтқым келеді. Мен сондай-ақ Apache Common пакетінің көмекші сыныптары арқылы осы әдістерді енгізу туралы жазамын. Java тіліндегі hashCode() және equals() әдістерімен жұмыс істеу - 1Осы посттың мазмұны:
  1. пайдалану hashCode()және equals().
  2. Әдепкі әрекетті қайта анықтау.
  3. Apache Commons Lang тілін қайта анықтау hashCode()және equals()пайдалану.
  4. Есте сақтау маңызды нәрсе.
  5. ORM пайдалану кезінде ерекше назар аударыңыз.
hashCode()және әдістері java нысандары үшін ата-аналық класс болып табылатын equals()сыныпта анықталған . ObjectСондықтан барлық java нысандары осы әдістерден әдепкі іске асыруды мұраға алады.

hashCode() және equals() пайдалану

Әдіс hashCode()берілген нысан үшін бірегей бүтін санды алу үшін қолданылады. Нысанды хэш кестесінде деректер құрылымы ретінде сақтау қажет болғанда (шелек деп те аталады), бұл сан оның сол кестедегі орнын анықтау үшін пайдаланылады. Әдепкі бойынша, hashCode()нысан әдісі нысан сақталатын жад орнының нөмірін қайтарады. Әдісі equals(), оның аты айтып тұрғандай, екі нысанның теңдігін тексеру үшін қолданылады. Бұл әдістің әдепкі орындалуы екі нысанның сілтемелерін олардың баламалы екендігін тексеру үшін тексереді.

Әдепкі әрекетті қайта анықтау

Сабақтарыңызда осы әдістердің ешқайсысын қайталамасаңыз, бәрі жақсы жұмыс істейді. Бірақ кейде қолданбалар кейбір нысандардың әдепкі әрекетін өзгертуі керек. Сізде бар мысалды алайық Employee. Мұндай класстың ең аз мүмкін құрылымын жазайық.
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;
    }
}
Жоғарыда сипатталған сыныпта Employeeкейбір негізгі атрибуттар мен аксессуар әдістері бар. Енді класстың екі an objectісін салыстыру қажет қарапайым жағдайды қарастырайық 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));
    }
}
Жоғарыда аталған әдіс «жалған» болып шығатынын болжау үшін көріпкелдің қажеті жоқ. Бірақ бұл екі нысанның бірдей екенін ескере отырып, бұл шынымен дұрыс па? Нақты уақыттағы қолданбада әдіс шын мәнін қайтаруы керек. equals()Дұрыс әрекетке жету үшін төменде орындалғандай әдісті қайта анықтауымыз керек :
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());
}
Бұл әдісті сыныпқа қосыңыз Employeeжәне баламалылықты тексеру «шын» мәнін береді. Дегенмен, біз бәрін жасадық па? Әзірше емес. Өзгертілген сыныбымызды тағы бір жолмен сынап көрейік.
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);
    }
}
Пәрмен System.out.println(employee)екі нысанды басып шығарады. Егер екі нысан да баламалы болса және Setтек бірегей нысандар ғана қамтылған болса, онда оның HashSetішінде бір ғана данасы болуы керек, яғни. екі нысан сыныптың бірдей даналарына сілтеме жасайды Employee. Біз нені сағындық? Біз екінші маңызды әдісті жіберіп алдық hashCode(). Java құжаттамасында айтылғандай, әдісті қайта анықтасаңыз equals(), әдісті қайта анықтау қажет hashCode(). Ендеше сабағымызға тағы бір әдісті қосайық Employee.
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + getId();
    return result;
 }
Біз бұл әдісті сыныпқа бір рет қостық, тек бір нысан басып шығарылады, осылайша e1 және e2 эквиваленттілігін тексеру шындықты көрсетті.

Apache Commons Lang тілін қайта анықтау hashCode()және пайдалануequals()

hashCode()Apache Commons және әдістерін шақыру үшін екі тамаша көмекші сыныпты ұсынады equals(). Төменде біз пайдалануды көреміз:
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();
    }
 }
Екінші жағынан, егер сіз code редакторларының бірін пайдалансаңыз, олар сізге жақсы құрылымдарды шақыра алуы керек. Мысалы, Eclipse IDE жүйесінде >> көзі > HeshCode() және equals() генерациялау класын тінтуірдің оң жақ түймешігімен бассаңыз ... бұл сіз үшін өте жақсы іске асыруды жасайды. Java тілінде hashCode() және equals() әдістерімен жұмыс істеу - 2Есте сақтау маңызды нәрсе.
  1. hashCode()Әрқашан және екеуін де шақыру үшін бірдей нысан атрибуттарын пайдаланыңыз equals(). Тек біздің жағдайда біз қолдандық employee id.
  2. Әдіс equals()тұрақты болуы керек (егер нысан өзгермеген болса, әдіс бірдей мәнді қайтаруы керек).
  3. Кез келген уақытта a.equals(b), содан кейін a.hashCode()бірдей болуы керек b.hashCode().
  4. Бір әдісті қайта анықтасаңыз, екіншісін қайта анықтауыңыз керек.

ORM пайдалану кезінде ерекше назар аударыңыз

Егер сіз ORM-мен (ru.wikipedia.org/wiki/ORM) жұмыс істеп жатсаңыз, онда әрқашан алушыларды пайдаланыңыз және ешқашан өріс сілтемелерін пайдаланбаңыз hashCode(). equals()Себебі ORM жүйесінде мезгіл-мезгіл өрістер жалқау жүктеме арқылы жүктеледі және олардың қабылдаушылары шақырылғанға дейін қол жетімді болмайды. Мысалы, біздің сыныпта Employeeбіз пайдаланамыз e1.id == e2.id. id өрістері жалқау жүктеу арқылы жүктелуі әбден мүмкін . Өрістердің бірі 0 немесе нөл болуы мүмкін және біз дұрыс емес әрекетті аламыз. Бірақ, егер , қолданылса e1.getId() == e2.getId(), өрістер жалқау жүктеу арқылы жүктелгеніне де сенімді бола аламыз; алушыны шақыру алдымен өрісті толтырады. hashCode()Бұл мен әдістері туралы білетінім equals(). Бұл біреуге бір жерде көмектеседі деп үміттенемін. Оқуыңа сәттілік!! ps Бұл менің аудармадағы бірінші әрекетім. Мен бәрін автордың айтқысы келгеніне барынша жақын жеткізуге тырыстым. Пікірлеріңіз болса, түсініктемелерде жазыңыз. Қатаң баға бермеңіз :-))) Түпнұсқа мақала
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION