Бұл мақалада мен әдістер туралы түсінігімді Apache Commons Lang тілін қайта анықтау
hashCode()
және equals()
. Мен олардың әдепкі орындалуы туралы, сондай-ақ оларды қалай дұрыс қайта анықтау керектігі туралы айтқым келеді. Мен сондай-ақ Apache Common пакетінің көмекші сыныптары арқылы осы әдістерді енгізу туралы жазамын. Осы посттың мазмұны:
- пайдалану
hashCode()
жәнеequals()
. - Әдепкі әрекетті қайта анықтау.
- Apache Commons Lang тілін қайта анықтау
hashCode()
жәнеequals()
пайдалану. - Есте сақтау маңызды нәрсе.
- 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() генерациялау класын тінтуірдің оң жақ түймешігімен бассаңыз ... бұл сіз үшін өте жақсы іске асыруды жасайды. Есте сақтау маңызды нәрсе.
hashCode()
Әрқашан және екеуін де шақыру үшін бірдей нысан атрибуттарын пайдаланыңызequals()
. Тек біздің жағдайда біз қолдандықemployee id
.- Әдіс
equals()
тұрақты болуы керек (егер нысан өзгермеген болса, әдіс бірдей мәнді қайтаруы керек). - Кез келген уақытта
a.equals(b)
, содан кейінa.hashCode()
бірдей болуы керекb.hashCode()
. - Бір әдісті қайта анықтасаңыз, екіншісін қайта анықтауыңыз керек.
ORM пайдалану кезінде ерекше назар аударыңыз
Егер сіз ORM-мен (ru.wikipedia.org/wiki/ORM) жұмыс істеп жатсаңыз, онда әрқашан алушыларды пайдаланыңыз және ешқашан өріс сілтемелерін пайдаланбаңызhashCode()
. equals()
Себебі ORM жүйесінде мезгіл-мезгіл өрістер жалқау жүктеме арқылы жүктеледі және олардың қабылдаушылары шақырылғанға дейін қол жетімді болмайды. Мысалы, біздің сыныпта Employee
біз пайдаланамыз e1.id == e2.id
. i
d өрістері жалқау жүктеу арқылы жүктелуі әбден мүмкін . Өрістердің бірі 0 немесе нөл болуы мүмкін және біз дұрыс емес әрекетті аламыз. Бірақ, егер , қолданылса e1.getId() == e2.getId()
, өрістер жалқау жүктеу арқылы жүктелгеніне де сенімді бола аламыз; алушыны шақыру алдымен өрісті толтырады. hashCode()
Бұл мен әдістері туралы білетінім equals()
. Бұл біреуге бір жерде көмектеседі деп үміттенемін. Оқуыңа сәттілік!! ps Бұл менің аудармадағы бірінші әрекетім. Мен бәрін автордың айтқысы келгеніне барынша жақын жеткізуге тырыстым. Пікірлеріңіз болса, түсініктемелерде жазыңыз. Қатаң баға бермеңіз :-))) Түпнұсқа мақала
GO TO FULL VERSION