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 equalspamamaraan ay hindi limitado sa Stringklase. Bawat klase meron nito.
Maging ang mga klase na ikaw mismo ang nagsusulat, at narito kung bakit.
2. Objectklase
Lahat ng klase sa Java ay nagmamana ng Objectklase. Ang mga tagalikha ng Java ay gumawa ng diskarteng ito.
At kung ang isang klase ay nagmamana ng Objectklase, pagkatapos ay nakukuha nito ang lahat ng mga pamamaraan ng Objectklase. At ito ay isang malaking kahihinatnan ng mana.
Sa madaling salita, ang bawat klase ay may mga pamamaraan ng Objectklase, 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 Personklase na may mga parameter ng pangalan at edad, ngunit hindi isang paraan. Ngunit dahil namamana ng lahat ng klase ang Objectklase, Personawtomatikong 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 equalspamamaraan, 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 Objectklase, 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 Personang mga variable sa halip na tawagan ang equals()pamamaraan. Halimbawa:
| Code | Output ng console |
|---|---|
|
|
Kapag equalstinawag ang pamamaraan sa a, inihahambing lamang nito ang reference na nakaimbak sa avariable sa reference na nakaimbak sa bvariable.
Gayunpaman, ang paghahambing ay gumagana nang iba para sa Stringklase. Bakit?
Dahil ang mga taong lumikha ng Stringklase 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 Personklase. Isasaalang-alang namin ang 4 na pangunahing kaso.
equalspamamaraan, palaging tumatagal ng isang Objectbagay bilang isang argumento
Sitwasyon 1 : ang parehong bagay kung saan equalstinatawag ang pamamaraan ay ipinapasa din sa equalspamamaraan. 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 : nullay ipinasa sa equalspamamaraan — wala tayong maihahambing. Ang bagay kung saan equalstinawag ang pamamaraan ay tiyak na hindi null, kaya kailangan nating bumalik falsesa 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 Personay ipinasa sa equalspamamaraan. Ang Personbagay ba ay katumbas ng hindi Personbagay? Iyon ay isang tanong para sa developer ng Personklase 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 Personklase 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 instanceofoperator.
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 Personbagay
Ano ang natapos namin? Kung naabot na natin ang dulo ng pamamaraan, mayroon tayong Personobject reference na hindi null. Kaya't iko-convert namin ito sa isang Personat 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 Personbagay? 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 equalspamamaraan.
this.name.equals(person.name)
Pangalawa, ang namefield ay maaaring null: sa kasong iyon, hindi ka maaaring tumawag equalsdito. 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 nullnasa parehong Personmga 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.nameay katumbas ng null, walang punto sa paghahambing gamit ang equalspamamaraan. Dito, ang pangalawang namefield ay katumbas ng null, o hindi. Ihambing ang dalawang patlang ng pangalan gamit ang equalspamamaraan. |
5. hashCode()paraan
Bilang karagdagan sa equalspamamaraan, 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 Objectklase), 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 equalspamamaraan.
Nangangahulugan iyon na kung bibigyan mo ang iyong sariling klase ng isang equalspamamaraan 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