equals
baglanyşyklydygyny hashCode
we bu usullaryň ikisini-de sapaklarynda yzygiderli ýok etmegiň maslahat berilýändigini bilýärler. Birneme az sanly adam munuň näme üçin beýle bolýandygyny we bu düzgün bozulsa nähili gynandyryjy netijeleriň bolup biljekdigini bilýär. Bu usullaryň düşünjesini gözden geçirmegi, maksadyny gaýtalamagy we näme üçin beýle baglanyşýandygyna düşünmegi teklip edýärin. Bu makalany, meseläniň ähli jikme-jikliklerini aýan etmek we indi üçünji tarap çeşmelerine gaýdyp gelmezlik üçin, sapaklary ýüklemek baradaky öňki ýaly bolşy ýaly ýazdym. Şonuň üçin konstruktiw tankyt etmekden hoşal bolaryn, sebäbi bir ýerde boşluklar bar bolsa, olary ýok etmeli. Makala, gaty uzyn bolup çykdy.
ýok etmek düzgünlerine deňdir
Java-da bir gelip çykyşy bolan iki obýektiň logiki taýdan deňdigini tassyklamak ýa-da inkär etmek üçin bir usulequals()
gerek . Twoagny, iki obýekti deňeşdireniňde, programmist olaryň möhüm meýdanlarynyň deňdigine ýa-da ýokdugyna düşünmeli . Fieldshli meýdanlaryň birmeňzeş bolmagy hökman däl, sebäbi usul logiki deňligi göz öňünde tutýar . Emma käwagt bu usuly ulanmagyň aýratyn zerurlygy ýok. Aýdyşlary ýaly, belli bir mehanizmi ulanmak bilen kynçylyklardan gaça durmagyň iň aňsat usuly ony ulanmazlykdyr. Şertnamany bozanyňyzdan soň, beýleki obýektleriň we gurluşlaryň obýektiňiz bilen nähili täsirleşjekdigine düşünip bilmejekdigiňizi hem bellemelidiris . Soň bolsa ýalňyşlygyň sebäbini tapmak gaty kyn bolar. equals()
equals
Haçan-da bu usuly ýok etmeli däl
- Haçan-da synpyň her mysaly özboluşly bolsa. Has köp derejede, bu maglumatlar bilen işlemek üçin däl-de, belli bir özüni alyp barşy üpjün edýän synplara degişlidir. Mysal üçin, synp ýaly
- Aslynda synp öz ýagdaýlarynyň ekwiwalentligini kesgitlemek talap edilmeýär. Mysal üçin, synp üçin
- Giňeldýän synpyňyzda eýýäm usulyň ýerine ýetirilişi bar
equals
we bu ýerine ýetirişiň özüni alyp barşy size laýyk gelýär. Mysal üçin, synplar - Netijede,
equals
synpyňyzyň gerimiprivate
ýapackage-private
-da bu usulyň hiç haçan çagyrylmajakdygyna ynanýarsyňyz.
Thread
. Olar üçin equals
synp tarapyndan berlen usulyň durmuşa geçirilmegi Object
ýeterlik däl. Başga bir mysal, enum synplary ( Enum
).
java.util.Random
synplaryň mysallaryny biri-biri bilen deňeşdirip, tötänleýin sanlaryň birmeňzeş yzygiderliligini yzyna gaýtaryp biljekdigini kesgitlemek zerurlygy ýok. Diňe bu synpyň tebigaty beýle hereketi aňlatmaýar.
Set
üçin ýerine ýetiriş we List
degişlilikde . Map
equals
AbstractSet
AbstractList
AbstractMap
şertnamasyna deňdir
Usuly ýok edende,equals
dörediji Java dil spesifikasiýasynda kesgitlenen esasy düzgünleri berjaý etmeli.
- Reflekslilik islendik baha üçin
- Simmetriýa berlen bahalar üçin
- Geçiş berlen bahalar üçin ,
- Yzygiderlilik berlen bahalar üçin
- Deňeşdirme null islendik baha üçin
x
aňlatma x.equals(x)
gaýdyp gelmeli true
.
Berildi - munuň manysy
x != null
x
we y
diňe gaýdyp gelse x.equals(y)
gaýdyp gelmeli . true
y.equals(x)
true
x
we y
gaýdyp gelse z
, bahany yzyna gaýtarmaly . x.equals(y)
true
y.equals(z)
true
x.equals(z)
true
x
we y
gaýtalanýan jaň , x.equals(y)
iki obýekti deňeşdirmek üçin ulanylýan meýdanlar jaňlaryň arasynda üýtgemese, öňki jaňyň bahasyny şu usula gaýtaryp berer.
x
jaň x.equals(null)
gaýdyp gelmeli false
.
şertnamanyň bozulmagyna deňdir
Java kolleksiýalarynyň çarçuwasy ýaly köp synplar usulyň durmuşa geçirilmegine baglydyrequals()
, şonuň üçin ony äsgermezlik etmeli däl, sebäbi Bu usulyň şertnamasynyň bozulmagy programmanyň manysyz işlemegine sebäp bolup biler we bu ýagdaýda sebäbini tapmak gaty kyn bolar. Reflekslilik ýörelgesine görä , her bir jisim özüne deň bolmaly. Bu ýörelge bozulan bolsa, kolleksiýa bir zat goşup, ony usul bilen gözlänimizde, contains()
kolleksiýa ýaňy goşan zadymyzy tapyp bilmeris. Simmetriýa şerti , haýsy iki obýektiň deňeşdirilendigine garamazdan deň bolmalydygyny aýdýar. equals
Mysal üçin, diňe bir görnüşli setir görnüşini öz içine alýan synpyňyz bar bolsa, bu meýdany usul bilen setir bilen deňeşdirmek nädogry bolar . Sebäbi ters deňeşdirme bolan ýagdaýynda usul hemişe bahany yzyna gaýtaryp berer false
.
// Нарушение симметричности
public class SomeStringify {
private String s;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof SomeStringify) {
return s.equals(((SomeStringify) o).s);
}
// нарушение симметричности, классы разного происхождения
if (o instanceof String) {
return s.equals(o);
}
return false;
}
}
//Правильное определение метода equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
return o instanceof SomeStringify &&
((SomeStringify) o).s.equals(s);
}
Geçiş ýagdaýyndan üç jisimiň ikisi deň bolsa, bu ýagdaýda üçüsi hem deň bolmaly diýilýär. Belli bir esasy synpy oňa manyly komponent goşmak bilen giňeltmek zerur bolanda bu ýörelgäni aňsatlyk bilen bozup bolar . Point
Mysal üçin, koordinatlar bilen bir klasa x
we y
nokadyň reňkini giňeltmek bilen goşmaly. ColorPoint
Munuň üçin degişli meýdan bilen synp yglan etmeli bolarsyňyz color
. Şeýlelik bilen, giňeldilen synpda ene-atanyň usuly diýýäris we ene-atada diňe koordinatlar we deňeşdirilýär equals
diýip çaklaýarys , onda dürli reňkli, ýöne birmeňzeş koordinatlar bilen iki nokat deň hasap ediler, bu nädogry. Bu ýagdaýda alnan synpy reňkleri tapawutlandyrmagy öwretmek zerurdyr. Munuň üçin iki usuly ulanyp bilersiňiz. Emma biri simmetriýanyň düzgünini , ikinjisi - geçişliligini bozar . x
y
// Первый способ, нарушая симметричность
// Метод переопределен в классе ColorPoint
@Override
public boolean equals(Object o) {
if (!(o instanceof ColorPoint)) return false;
return super.equals(o) && ((ColorPoint) o).color == color;
}
Bu ýagdaýda jaň point.equals(colorPoint)
gymmaty yzyna getirer true
we deňeşdirme colorPoint.equals(point)
gaýdyp geler false
, sebäbi “synp” obýektine garaşýar. Şeýlelik bilen simmetriýanyň düzgüni bozulýar. Ikinji usul, nokadyň reňki barada maglumat ýok bolsa, ýagny synpymyz bar bolsa, "kör" barlagy öz içine alýar Point
. Ora-da bu hakda maglumat bar bolsa, reňkini barlaň, ýagny synpyň obýektini deňeşdiriň ColorPoint
.
// Метод переопределен в классе ColorPoint
@Override
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
// Слепая проверка
if (!(o instanceof ColorPoint))
return super.equals(o);
// Полная проверка, включая цвет точки
return super.equals(o) && ((ColorPoint) o).color == color;
}
Geçiş ýörelgesi şu ýerde aşakdaky ýaly bozulýar. Aşakdaky obýektleriň kesgitlemesi bar diýeliň:
ColorPoint p1 = new ColorPoint(1, 2, Color.RED);
Point p2 = new Point(1, 2);
ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
Şeýlelik bilen, deňlik p1.equals(p2)
we kanagatly bolsa-da p2.equals(p3)
, p1.equals(p3)
gymmaty yzyna getirer false
. Şol bir wagtyň özünde, ikinji usul, meniň pikirimçe, az özüne çekiji görünýär, sebäbi Käbir hadysalarda algoritm kör bolup, deňeşdirmäni doly ýerine ýetirip bilmez we bu hakda bilmezligiňiz mümkin. Biraz goşgy Umuman, düşünşim ýaly, bu meseläniň anyk çözgüdi ýok. Keý Horstmann atly bir abraýly ýazyjynyň pikirine görä, operatoryň ulanylyşyny obýektiň synpyny yzyna gaýtarýan instanceof
usul jaňy bilen çalşyp bilersiňiz getClass()
we obýektleriň özlerini deňeşdirip başlamazdan ozal olaryň birmeňzeşdigine göz ýetiriň. we umumy gelip çykyşyna üns bermäň. Şeýlelik bilen, simmetriýanyň we geçiş düzgünleri kanagatlandyrylar. Emma şol bir wagtyň özünde, barrikadanyň beýleki tarapynda giň çemeleşmelerde hormat goýulmaýan başga bir ýazyjy Joşua Bloç dur, bu çemeleşme Barbara Liskowyň ornuny tutýar diýip hasaplaýar. Bu ýörelge , "çagyryş kody esasy synpy bilmän, öz kiçi klaslary ýaly garamalydyr " diýilýär . Horstmann tarapyndan teklip edilen çözgütde bu ýörelge aç-açan bozulýar, sebäbi durmuşa geçirilmegine bagly. Gysgaça aýdylanda, meseläniň garaňkydygy aýdyňdyr. Şeýle hem Horstmanyň çemeleşmesini ulanmagyň düzgünini aýdyňlaşdyrýandygyny we sapaklary düzeniňizde strategiýa barada karar bermelidigiňizi we iňlis dilinde aç-açan ýazýandygyny, deňlik synagy diňe superklass tarapyndan geçiriljek bolsa, muny ýerine ýetirip bilersiňiz operasiýa instanceof
. Otherwiseogsam, alnan synplara we usulyň ýerine ýetirilişine baglylykda barlagyň semantikasy üýtgese, usuly ulanmaly getClass()
. ColorPoint
Joşua Bloç hem öz gezeginde mirasa ýüz öwürmegi we synpyň içine bir synp goşmak we bu nokat barada ýörite maglumat almak üçin Point
giriş usulyny bermek arkaly obýektiň düzümini ulanmagy teklip edýär . asPoint()
Bu, ähli düzgünleri bozmakdan gaça durar, ýöne, meniň pikirimçe, kody düşünmek has kynlaşdyrar. Üçünji wariant, IDE ulanyp, deň usulyň awtomatiki öndürilmegini ulanmak. Ideaeri gelende aýtsak, ideýa superklasda ýa-da onuň nesillerinde usuly durmuşa geçirmegiň strategiýasyny saýlamaga mümkinçilik berýän Horstmann neslini köpeldýär. Netijede, indiki yzygiderlilik düzgüni , obýektler üýtgemese-de x
, y
olary täzeden çagyrmak x.equals(y)
öňküsi ýaly bahany yzyna gaýtarmalydygyny aýdýar. Iň soňky düzgün, hiç bir obýektiň deň bolmazlygydyr null
. Bu ýerde hemme zat düşnükli null
- bu näbellilik, obýekt näbellilige deňmi? Bu düşnükli däl false
.
Deňligi kesgitlemek üçin umumy algoritm
this
Obýekt salgylanmalarynyň we usul parametrleriniň deňligini barlaňo
.if (this == o) return true;
- Baglanyşygyň kesgitlenendigini
o
ýa-da ýokdugyny barlaňnull
.
Geljekde obýektiň görnüşlerini deňeşdireniňde, operator ulanylarinstanceof
, bu element geçip biler, sebäbi bu parametrfalse
bu ýagdaýda gaýdyp gelýärnull instanceof Object
. - Aboveokardaky düşündirişe we öz duýgurlygyňyza esaslanýan operator ýa-da usul
this
ulanyp , obýekt görnüşlerini deňeşdiriň .o
instanceof
getClass()
- Bir usul
equals
kiçi klasda ýok edilse, jaň ediňsuper.equals(o)
- Parametr görnüşini
o
zerur klasa öwüriň. - Significanthli möhüm obýekt meýdanlaryny deňeşdiriň:
- operatory ulanyp, başlangyç görnüşler üçin (
float
we başga)double
==
- salgylanma meýdanlary üçin olaryň usulyna jaň etmeli
equals
- massiwler üçin siklik gaýtalama ýa-da usul ulanyp bilersiňiz
Arrays.equals()
- görnüşleri üçin
float
wedouble
degişli örtük synplarynyň deňeşdirme usullaryny ulanmalyFloat.compare()
weDouble.compare()
- operatory ulanyp, başlangyç görnüşler üçin (
- Netijede, üç soraga jogap beriň: ýerine ýetirilen usul simmetrikmi ? Geçişmi ? Ylalaşdyňyzmy ? Beýleki iki ýörelge ( reflekslilik we ynam ) adatça awtomatiki usulda amala aşyrylýar.
HashCode düzgünleri ýok edýär
Haş, belli bir wagtda ýagdaýyny suratlandyrýan obýektden emele gelen san. Bu san Java ýaly esasan hash tablisalarynda ulanylýarHashMap
. Bu ýagdaýda, obýekte esaslanýan san almagyň hash funksiýasy, hash tablisasynyň üstünde elementleriň deňeşdirip paýlanmagyny üpjün etmek üçin durmuşa geçirilmelidir. Şeýle hem, funksiýa dürli düwmeler üçin birmeňzeş bahany yzyna gaýtarsa, çaknyşmak ähtimallygyny azaltmak.
Şertnama hashCode
Haş funksiýasyny ýerine ýetirmek üçin dil spesifikasiýasy aşakdaky düzgünleri kesgitleýär:- usuly
hashCode
şol bir obýektde bir ýa-da birnäçe gezek çagyrmak, bahany hasaplamaga gatnaşýan obýektleriň meýdanlary üýtgemese, şol bir hash bahasyny yzyna gaýtarmalydyr. - iki obýektde usuly çagyrmak,
hashCode
obýektler deň bolsa, hemişe şol bir belgini yzyna gaýtarmaly (equals
bu obýektlere usuly çagyrmak gaýdyp gelýärtrue
). hashCode
iki sany deň bolmadyk obýektde usul çagyrmak, dürli hash bahalaryny yzyna gaýtarmaly. Bu talap hökmany bolmasa-da, ýerine ýetirilişiniň hash tablisalarynyň işine oňyn täsir etjekdigini göz öňünde tutmalydyrys.
Deňdir we hashCode usullary bilelikde ýok edilmeli
Aboveokarda beýan edilen şertnamalara esaslanyp, koduňyzdaky usuly ýok edendeequals
, usuly elmydama ýok etmeli bolarsyňyz hashCode
. Aslynda synpyň iki mysaly dürli ýat ýerlerinde bolany üçin dürli-dürli bolansoň, käbir logiki ölçeglere görä deňeşdirilmeli. Şoňa laýyklykda iki logiki taýdan ekwiwalent obýekt şol bir hash bahasyny yzyna gaýtarmaly. Bu usullaryň diňe biri ýok edilse näme bolar?
-
equals
HawahashCode
Ýokequals
Synpymyzda bir usuly dogry kesgitledik wehashCode
usuly synpdaky ýaly goýmagy makul bildikObject
. Soňra usulyň nukdaýnazaryndanequals
iki obýekt logiki taýdan deň bolar, usulyň nukdaýnazaryndanhashCode
umumylyk bolmaz. Şeýlelik bilen, bir zady hash tablisasyna ýerleşdirip, ony açar bilen yzyna almazlyk howpuny başdan geçirýäris.
Mysal üçin, şuňa meňzeş:Map<Point, String> m = new HashMap<>(); m.put(new Point(1, 1), “Point A”); // pointName == null String pointName = m.get(new Point(1, 1));
Elbetde, ýerleşdirilýän obýekt we gözlenýän obýekt logiki taýdan deň bolsa-da, iki dürli obýektdir. Emma, sebäbi şertnamany bozanymyz üçin dürli hash bahalary bar, heş tablisasynyň içegesinde bir zadymyzy ýitirendigimizi aýdyp bileris.
-
hashCode
Hawaequals
Ýok.Usuly ýok etsek
hashCode
weequals
usulyň ýerine ýetirilişini synpdan miras alsak näme bolýarObject
. Bilşiňiz ýaly,equals
deslapky usul görkezijileri obýektler bilen deňeşdirýär we olaryň şol bir obýekte degişlidigini kesgitleýär. Usuly ähli kanonlara laýyklykda ýazdykhashCode
, ýagny IDE ulanyp döreddik we logiki taýdan birmeňzeş obýektler üçin şol bir hash bahalaryny yzyna gaýtaryp bereliň. Elbetde, şeýle etmek bilen eýýäm iki jisimi deňeşdirmegiň käbir mehanizmini kesgitledik.Şonuň üçin öňki abzasdan mysal teoriýa boýunça amala aşyrylmalydyr. Stillöne henizem hash tablisasynda obýektimizi tapyp bilmeris. Muňa ýakyn bolsak-da, iň bolmanda obýektiň ýatjak hash stol sebedini taparys.
Haş tablisasyndaky obýekti üstünlikli gözlemek üçin, açaryň hash bahalaryny deňeşdirmekden başga-da, gözlenýän obýekt bilen açaryň logiki deňligini kesgitlemek hem ulanylýar. .Agny,
equals
usuly ýok etmezden hiç hili ýol ýok.
HashCode kesgitlemek üçin umumy algoritm
Ine, meniň pikirimçe, gaty köp alada etmeli däl we halaýan IDE-de usuly döretmeli däl. Sebäbi altyn gatnaşygy gözlemek üçin sag we çepe bitleriň bu üýtgemegi, adaty paýlanyş - bu düýbünden birkemsiz dudlar üçin. Özüm, şol bir ideýadan has gowy we has çalt edip biljekdigime şübhelenýärin.Netijäniň ýerine
Şeýlelik bilen, usullaryň Java dilinde gowy kesgitlenen rolequals
oýnaýandygyny we iki obýektiň logiki deňligini almak üçin döredilendigini görýäris . hashCode
Usul meselesinde equals
munuň obýektleri deňeşdirmek bilen gönüden-göni baglanyşygy bar, hashCode
gytaklaýyn bolsa, zerur bolanda, heş tablisalarynda ýa-da şuňa meňzeş maglumat gurluşlarynda obýektiň takmynan ýerleşişini kesgitlemek üçin aýdalyň. obýekt gözlemegiň tizligini ýokarlandyrmak. Şertnamalara goşmaça , obýektleri deňeşdirmek bilen baglanyşykly başga bir talap bar equals
. Bu, interfeýs usulynyň hashCode
yzygiderliligi . Bu talap işläp düzüjini hemişe haçan gaýdyp gelmäge borçly edýär . Twoagny, iki obýektiň logiki deňeşdirmesiniň programmanyň islendik ýerinde gapma-garşy bolmaly däldigini we hemişe yzygiderli bolmalydygyny görýäris. compareTo
Comparable
equals
x.equals(y) == true
x.compareTo(y) == 0
GO TO FULL VERSION