1. Paghahambing ng mga bagay sa Java
Sa Java, ang mga bagay ay maaaring ihambing pareho sa pamamagitan ng sanggunian at sa pamamagitan ng halaga.
Paghahambing ng mga sanggunian
Kung ang dalawang variable ay tumuturo sa parehong bagay sa memorya, kung gayon ang mga sanggunian na nakaimbak sa mga variable na ito ay pantay. Kung ihahambing mo ang mga variable na ito gamit ang equality operator ( ==
), makakakuha ka ng totoo, at ang resultang iyon ay may katuturan. Simple lang ang lahat dito.
Code | Output ng console |
---|---|
|
|
Paghahambing ayon sa halaga
Ngunit madalas kang makakatagpo ng mga sitwasyon kung saan ang dalawang variable ay tumutukoy sa dalawang natatanging bagay na magkapareho. Halimbawa, dalawang magkaibang string na mga bagay na naglalaman ng parehong teksto.
Upang matukoy kung magkapareho ang iba't ibang bagay, gamitin ang equals()
pamamaraan. Halimbawa:
Code | Output ng console |
---|---|
|
|
Ang equals
pamamaraan ay hindi limitado sa String
klase. Bawat klase meron nito.
Maging ang mga klase na ikaw mismo ang nagsusulat, at narito kung bakit.
2. Object
klase
Lahat ng klase sa Java ay nagmamana ng Object
klase. Ang mga tagalikha ng Java ay gumawa ng diskarteng ito.
At kung ang isang klase ay nagmamana ng Object
klase, pagkatapos ay nakukuha nito ang lahat ng mga pamamaraan ng Object
klase. At ito ay isang malaking kahihinatnan ng mana.
Sa madaling salita, ang bawat klase ay may mga pamamaraan ng Object
klase, kahit na ang kanilang code ay hindi binanggit ang mga ito.
Kasama sa mga minanang pamamaraang ito ang mga pamamaraang nauugnay sa paghahambing ng bagay. Ito ang mga equals()
at hashCode()
pamamaraan.
Code | Sa katotohanan, narito ang makukuha natin: |
---|---|
|
|
Sa halimbawa sa itaas, gumawa kami ng isang simpleng Person
klase na may mga parameter ng pangalan at edad, ngunit hindi isang paraan. Ngunit dahil namamana ng lahat ng klase ang Object
klase, Person
awtomatikong mayroong dalawang pamamaraan ang klase:
Pamamaraan | Paglalarawan |
---|---|
|
Inihahambing ang kasalukuyang bagay at ang naipasa na bagay |
|
Ibinabalik ang hashcode ng kasalukuyang bagay |
Ito ay lumalabas na ganap na ang bawat bagay ay may equals
pamamaraan, at ang mga bagay ng iba't ibang uri ay maaaring ihambing sa bawat isa. Ang ganitong code ay mag-compile at gagana nang perpekto.
Code | Output ng console |
---|---|
|
|
|
|
3. equals()
paraan
Ang equals()
pamamaraan, na minana mula sa Object
klase, ay nagpapatupad ng pinakasimpleng algorithm para sa paghahambing ng kasalukuyang bagay sa mga naipasa na bagay: ito ay naghahambing lamang ng mga sanggunian sa mga bagay.
Makakakuha ka ng parehong resulta kung ihahambing mo lamang Person
ang mga variable sa halip na tawagan ang equals()
pamamaraan. Halimbawa:
Code | Output ng console |
---|---|
|
|
Kapag equals
tinawag ang pamamaraan sa a
, inihahambing lamang nito ang reference na nakaimbak sa a
variable sa reference na nakaimbak sa b
variable.
Gayunpaman, ang paghahambing ay gumagana nang iba para sa String
klase. Bakit?
Dahil ang mga taong lumikha ng String
klase ay nagsulat ng kanilang sariling pagpapatupad ng equals()
pamamaraan.
Pagpapatupad ng equals()
pamamaraan
Ngayon ay isulat natin ang sarili nating pagpapatupad ng equals method sa Person
klase. Isasaalang-alang namin ang 4 na pangunahing kaso.
equals
pamamaraan, palaging tumatagal ng isang Object
bagay bilang isang argumento
Sitwasyon 1 : ang parehong bagay kung saan equals
tinatawag ang pamamaraan ay ipinapasa din sa equals
pamamaraan. Kung ang mga sanggunian ng kasalukuyang bagay at ang naipasa na bagay ay pantay, ang pamamaraan ay dapat bumalik true
. Ang isang bagay ay katumbas ng sarili nito.
Sa code ito ay magiging ganito:
Code | Paglalarawan |
---|---|
|
Ihambing ang mga sanggunian |
Scenario 2 : null
ay ipinasa sa equals
pamamaraan — wala tayong maihahambing. Ang bagay kung saan equals
tinawag ang pamamaraan ay tiyak na hindi null, kaya kailangan nating bumalik false
sa kasong ito.
Sa code ito ay magiging ganito:
Code | Paglalarawan |
---|---|
|
Ihambing ang mga sanggunian Ay ang naipasa bagay null ? |
Sitwasyon 3 : isang sanggunian sa isang bagay na hindi isang Person
ay ipinasa sa equals
pamamaraan. Ang Person
bagay ba ay katumbas ng hindi Person
bagay? Iyon ay isang tanong para sa developer ng Person
klase na magpasya kung ano man ang gusto niya.
Ngunit kadalasan ang mga bagay ay dapat sa parehong klase upang maituring na pantay. Samakatuwid, kung ang isang bagay maliban sa isang bagay ng Person
klase ay ipinasa sa aming katumbas na pamamaraan, pagkatapos ay palagi kaming babalik false
. Paano mo masusuri ang uri ng isang bagay? Tama iyon — sa pamamagitan ng paggamit ng instanceof
operator.
Narito ang hitsura ng aming bagong code:
Code | Paglalarawan |
---|---|
|
Ihambing ang mga sanggunian Ay ang naipasa bagay null ? Kung ang ipinasang bagay ay hindi a Person |
4. Paghahambing ng dalawang Person
bagay
Ano ang natapos namin? Kung naabot na natin ang dulo ng pamamaraan, mayroon tayong Person
object reference na hindi null
. Kaya't iko-convert namin ito sa isang Person
at inihambing ang nauugnay na panloob na data ng parehong mga bagay. At iyon ang aming ikaapat na senaryo .
Code | Paglalarawan |
---|---|
|
Ihambing ang mga sanggunian Ay ang naipasa bagay null ? Kung ang naipasa na bagay ay hindi isang Person Typecasting |
At paano mo ihahambing ang dalawang Person
bagay? Pantay sila kung magkapareho sila ng pangalan ( name
) at edad ( age
). Ang huling code ay magiging ganito:
Code | Paglalarawan |
---|---|
|
Ihambing ang mga sanggunian Ay ang naipasa bagay null ? Kung ang naipasa na bagay ay hindi isang Person Typecasting |
Ngunit hindi lang iyon.
Una, ang field ng pangalan ay isang String
, kaya kailangan mong ihambing ang field ng pangalan sa pamamagitan ng pagtawag sa equals
pamamaraan.
this.name.equals(person.name)
Pangalawa, ang name
field ay maaaring null
: sa kasong iyon, hindi ka maaaring tumawag equals
dito. Kailangan mo ng karagdagang tseke para sa null
:
this.name != null && this.name.equals(person.name)
Iyon ay sinabi, kung ang field ng pangalan ay null
nasa parehong Person
mga bagay, kung gayon ang mga pangalan ay pantay pa rin.
Ang code para sa ikaapat na senaryo ay maaaring magmukhang ganito:
|
Kung ang mga edad ay hindi pantay, kaagad return false Kung this.name ay katumbas ng null , walang punto sa paghahambing gamit ang equals pamamaraan. Dito, ang pangalawang name field ay katumbas ng null , o hindi. Ihambing ang dalawang patlang ng pangalan gamit ang equals pamamaraan. |
5. hashCode()
paraan
Bilang karagdagan sa equals
pamamaraan, na nilayon upang magsagawa ng isang detalyadong paghahambing ng lahat ng mga patlang ng parehong mga bagay, mayroong isa pang paraan na maaaring magamit para sa isang hindi tumpak ngunit napakabilis na paghahambing: hashCode()
.
Isipin na nag-uuri ka ayon sa alpabeto ng isang listahan ng libu-libong salita, at kailangan mong paulit-ulit na paghambingin ang mga pares ng mga salita. At ang mga salita ay mahaba, na binubuo ng maraming mga titik. Sa pangkalahatan, ang gayong paghahambing ay tatagal ng napakatagal.
Ngunit maaari itong mapabilis. Ipagpalagay na mayroon tayong mga salita na nagsisimula sa iba't ibang mga titik — malinaw agad na magkaiba ang mga ito. Ngunit kung nagsisimula sila sa parehong mga titik, hindi pa natin masasabi kung ano ang magiging resulta: maaaring magkapareho o magkaiba ang mga salita.
Ang hashCode()
pamamaraan ay gumagana gamit ang isang katulad na prinsipyo. Kung tatawagin mo ito sa isang bagay, nagbabalik ito ng ilang numero — kahalintulad ng unang titik sa isang salita. Ang numerong ito ay may mga sumusunod na katangian:
- Ang magkaparehong mga bagay ay palaging may parehong hashcode
- Ang iba't ibang mga bagay ay maaaring magkaroon ng parehong hashcode, o ang kanilang mga hashcode ay maaaring magkaiba
- Kung ang mga bagay ay may iba't ibang mga hashcode, kung gayon ang mga bagay ay tiyak na naiiba
Upang gawin itong mas malinaw, i-reframe natin ang mga katangiang ito sa mga tuntunin ng mga salita:
- Ang mga magkatulad na salita ay palaging may parehong mga unang titik.
- Ang iba't ibang salita ay maaaring magkaroon ng parehong mga unang titik, o ang kanilang mga unang titik ay maaaring magkaiba
- Kung ang mga salita ay may iba't ibang mga unang titik, kung gayon ang mga salita ay tiyak na naiiba
Ang huling pag-aari ay ginagamit upang mapabilis ang paghahambing ng mga bagay:
Una, kinakalkula ang mga hashcode ng dalawang bagay. Kung ang mga hashcode na ito ay iba, kung gayon ang mga bagay ay tiyak na naiiba, at hindi na kailangang ihambing pa ang mga ito.
Ngunit kung pareho ang mga hashcode, kailangan pa rin nating ikumpara ang mga bagay gamit ang equals method.
6. Mga kontrata sa code
Ang pag-uugali na inilarawan sa itaas ay dapat ipatupad ng lahat ng mga klase sa Java. Sa panahon ng compilation, walang paraan upang suriin kung ang mga bagay ay inihambing nang tama.
Ang mga programmer ng Java ay may unibersal na kasunduan na kung isusulat nila ang kanilang sariling pagpapatupad ng equals() na pamamaraan at sa gayon ay i-override ang karaniwang pagpapatupad (sa Object
klase), dapat din nilang isulat ang kanilang sariling pagpapatupad ng hashCode()
pamamaraan sa paraang ang mga nabanggit na panuntunan ay nasiyahan.
Ang kaayusan na ito ay tinatawag na kontrata .
Kung ipapatupad mo lamang ang equals()
o ang pamamaraan lamang hashCode()
sa iyong klase, kung gayon ikaw ay nasa matinding paglabag sa kontrata (nasira mo ang kasunduan). Huwag gawin ito.
Kung ginagamit ng ibang programmer ang iyong code, maaaring hindi ito gumana nang tama. Higit pa rito, gagamit ka ng code na umaasa sa pagsunod sa mga kontrata sa itaas.
Kapag naghahanap ng isang elemento, ang lahat ng mga koleksyon ng Java ay unang ihambing ang mga hashcode ng mga bagay, at pagkatapos ay magsagawa ng paghahambing gamit ang equals
pamamaraan.
Nangangahulugan iyon na kung bibigyan mo ang iyong sariling klase ng isang equals
pamamaraan ngunit hindi mo isinulat ang iyong sariling hashCode()
pamamaraan o hindi mo ito ipinatupad nang tama, kung gayon ang mga koleksyon ay maaaring hindi gumana nang tama sa iyong mga bagay.
Halimbawa, maaari kang magdagdag ng isang bagay sa isang listahan at pagkatapos ay hanapin ito gamit ang contains()
pamamaraan, ngunit maaaring hindi mahanap ng koleksyon ang iyong bagay.
GO TO FULL VERSION