CodeGym /Java Blog /Random /Ihambing ang mga paghahambing ng String at Equals sa Java...
John Squirrels
Antas
San Francisco

Ihambing ang mga paghahambing ng String at Equals sa Java

Nai-publish sa grupo
Hi! Ngayon ay pag-uusapan natin ang tungkol sa isang napakahalaga at kawili-wiling paksa, ibig sabihin, paghahambing ng mga bagay sa mga bagay (Ihambing ang mga String at Equals). Kaya sa Java, kailan eksaktong magiging katumbas ng object B ang object A ? Subukan nating magsulat ng isang halimbawa:

public class Car {

   String model;
   int maxSpeed;

   public static void main(String[] args) {
      
       Car car1 = new Car();
       car1.model = "Ferrari";
       car1.maxSpeed = 300;

       Car car2 = new Car();
       car2.model = "Ferrari";
       car2.maxSpeed = 300;

       System.out.println(car1 == car2);
   }
}
Output ng console: false Wait, stop. Bakit hindi magkapantay ang dalawang sasakyan na ito? Nagtalaga kami sa kanila ng parehong mga katangian, ngunit ang resulta ng paghahambing ay mali. Simple lang ang sagot. Ang == operator ay naghahambing ng mga sanggunian sa bagay, hindi sa mga katangian ng bagay. Ang dalawang bagay ay maaaring magkaroon ng 500 mga patlang na may magkaparehong mga halaga, ngunit ang paghahambing sa mga ito ay magbubunga pa rin ng mali. Pagkatapos ng lahat, tumutukoy sa car1 at car2tumuro sa dalawang magkaibang bagay, ibig sabihin, sa dalawang magkaibang address. Isipin ang isang sitwasyon kung saan naghahambing ka ng mga tao. Tiyak, sa isang lugar sa mundo mayroong isang tao na kapareho ng pangalan mo, kulay ng mata, edad, taas, kulay ng buhok, atbp. Dahil dito, magkapareho kayo sa maraming aspeto, ngunit hindi pa rin kayo kambal — at halatang hindi kayo ang parehong tao.
Mga katumbas at paghahambing ng string - 2
Ang == operator ay gumagamit ng humigit-kumulang sa parehong logic kapag ginagamit namin ito upang ihambing ang dalawang bagay. Ngunit paano kung kailangan mo ang iyong programa na gumamit ng ibang lohika? Halimbawa, ipagpalagay na ang iyong programa ay nagsasagawa ng pagsusuri sa DNA. Inihahambing nito ang genetic code ng dalawang tao, at tinutukoy kung sila ay kambal.

public class Man {

   int geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = 1111222233;

       Man man2 = new Man();
       man2.geneticCode = 1111222233;

       System.out.println(man1 == man2);
   }
}
Console output: false Nakukuha namin ang parehong lohikal na resulta (dahil hindi kami masyadong nagbago), ngunit ngayon ang logic na iyon ay hindi maganda! Pagkatapos ng lahat, sa totoong buhay, ang pagsusuri sa DNA ay dapat magbigay sa amin ng 100% na garantiya na mayroon kaming kambal na nakatayo sa harap namin. Ngunit ang aming programa at ang == operator ay nagsasabi sa amin ng kabaligtaran. Paano natin babaguhin ang pag-uugaling ito at tinitiyak na ang programa ay maglalabas ng tamang resulta kapag tumugma ang DNA? Ang Java ay may espesyal na pamamaraan para dito: equals() . Tulad ng toString() method, na tinalakay natin kanina, equals() ay kabilang sa Object class — ang pinakamahalagang klase sa Java, ang klase kung saan nagmula ang lahat ng iba pang klase. Ngunit katumbas ng()ay hindi nagbabago sa pag-uugali ng aming programa nang mag-isa:

public class Man {

   String geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = "111122223333";

       Man man2 = new Man();
       man2.geneticCode = "111122223333";

       System.out.println(man1.equals(man2));
   }
}
Console output: false Eksakto sa parehong resulta, kaya para saan namin kailangan ang paraang ito? :/ Simple lang lahat. Ang isyu dito ay kasalukuyang ginagamit namin ang paraang ito dahil ipinapatupad ito sa klase ng Object . At kung pupunta tayo sa code ng klase ng Bagay at titingnan ang pagpapatupad ng pamamaraan, ito ang makikita natin:

public boolean equals(Object obj) {
   return (this == obj);
}
Iyon ang dahilan kung bakit hindi nagbago ang ugali ng programa! Ang parehong == operator (na naghahambing ng mga sanggunian) ay ginagamit sa loob ng equals() na pamamaraan ng Object class. Ngunit ang trick sa pamamaraang ito ay maaari nating i-override ito. Ang ibig sabihin ng pag-override ay isulat ang iyong sariling equals() na pamamaraan sa aming klase ng Man , na nagbibigay dito ng pag-uugali na kailangan namin! Sa kasalukuyan, hindi namin gusto ang katotohanan na ang man1.equals(man2) ay mahalagang katumbas ng man1 == man2 . Narito ang gagawin natin sa sitwasyong ito:

public class Man { 

   int dnaCode; 

   public boolean equals(Man man) { 
       return this.dnaCode ==  man.dnaCode; 

   } 

   public static void main(String[] args) { 

       Man man1 = new Man(); 
       man1.dnaCode = 1111222233; 

       Man man2 = new Man(); 
       man2.dnaCode = 1111222233; 

       System.out.println(man1.equals(man2)); 

   } 
} 
Output ng console: true Ngayon nakakakuha kami ng ganap na kakaibang resulta! Sa pamamagitan ng pagsusulat ng sarili naming equals() na pamamaraan at paggamit nito sa halip na ang pamantayan, nagawa namin ang tamang pag-uugali: Ngayon kung ang dalawang tao ay may parehong DNA, ang programa ay nag-uulat ng "Napatunayan ng pagsusuri ng DNA na sila ay kambal" at nagbabalik ng totoo! Sa pamamagitan ng pag-override sa equals() na pamamaraan sa iyong mga klase, madali kang makakagawa ng anumang lohika ng paghahambing ng object na kailangan mo. Sa katunayan, nahawakan lamang namin ang paghahambing ng bagay. Sa unahan natin, mayroon pa ring malaking nakapag-iisang aralin tungkol sa paksang ito (i-skim mo ito ngayon kung interesado ka).

Paghahambing ng mga string sa Java

Bakit namin isinasaalang-alang ang mga paghahambing ng string nang hiwalay sa lahat ng iba pa? Ang katotohanan ay ang mga string ay isang paksa sa kanilang sariling karapatan sa programming. Una, kung kukunin mo ang lahat ng mga Java program na kailanman naisulat, makikita mo na ang tungkol sa 25% ng mga bagay sa mga ito ay mga string. Kaya ang paksang ito ay napakahalaga. Pangalawa, ang proseso ng paghahambing ng mga string ay talagang ibang-iba sa ibang mga bagay. Isaalang-alang ang isang simpleng halimbawa:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
Output ng console: false Ngunit bakit kami nakakuha ng false? Pagkatapos ng lahat, ang mga string ay eksaktong pareho, salita para sa salita :/ Maaaring nahulaan mo ang dahilan: ito ay dahil ang == operator ay naghahambing ng mga sanggunian ! Maliwanag, ang s1 at s2 ay may magkaibang mga address sa memorya. Kung naisip mo iyon, gawin nating muli ang ating halimbawa:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       System.out.println(s1 == s2);
   }
}
Ngayon ay mayroon kaming dalawang sanggunian, ngunit ang resulta ay ang eksaktong kabaligtaran: Console output: true Helplessly confused? Alamin natin kung ano ang nangyayari. Ang == operator ay talagang naghahambing ng mga address ng memorya. Ito ay palaging totoo at hindi mo kailangang pagdudahan ito. Nangangahulugan iyon na kung ang s1 == s2 ay nagbabalik ng totoo, ang dalawang string na ito ay may parehong address. At totoo nga ito! Panahon na upang ipakilala sa iyo ang isang espesyal na lugar ng memorya para sa pag-iimbak ng mga string: ang string pool
Mga katumbas at paghahambing ng string - 3
Ang string pool ay isang lugar para sa pag-iimbak ng lahat ng mga halaga ng string na iyong nilikha sa iyong programa. Bakit ito nilikha? Tulad ng sinabi namin dati, ang mga string ay kumakatawan sa isang malaking porsyento ng lahat ng mga bagay. Ang anumang malaking programa ay lumilikha ng maraming mga string. Ang string pool ay nilikha upang makatipid ng memorya: ang mga string ay inilalagay doon at pagkatapos ay ang mga kasunod na nilikha na mga string ay tumutukoy sa parehong lugar ng memorya-hindi na kailangang maglaan ng karagdagang memorya sa bawat oras. Sa tuwing isusulat mo ang String = "........" sinusuri ng program kung mayroong magkaparehong string sa string pool. Kung mayroon, hindi gagawa ng bagong string. At ang bagong reference ay ituturo sa parehong address sa string pool (kung saan matatagpuan ang magkaparehong string). Kaya nung nagsulat kami

String s1 = "CodeGym is the best website for learning Java!";
String s2 = "CodeGym is the best website for learning Java!";
Ang s2 ay tumuturo sa parehong lugar bilang s1 . Ang unang pahayag ay lumilikha ng bagong string sa string pool. Ang pangalawang pahayag ay tumutukoy lamang sa parehong lugar ng memorya bilang s1 . Maaari kang gumawa ng isa pang 500 magkaparehong mga string at ang resulta ay hindi magbabago. Sandali lang. Kung totoo iyon, bakit hindi gumana ang halimbawang ito noon?

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
I think nasabi na sa iyo ng intuition mo ang dahilan =) Try to guess before reading further. Makikita mo na ang dalawang string na ito ay idineklara sa magkaibang paraan. Ang isa ay may bagong operator, at ang isa ay wala nito. Dito nakasalalay ang dahilan. Kapag ginamit ang bagong operator upang lumikha ng isang bagay, pilit itong naglalaan ng bagong lugar ng memorya para sa bagay. At ang isang string na ginawa gamit ang bago ay hindi napupunta sa string pool - ito ay nagiging isang hiwalay na bagay, kahit na ang teksto nito ay perpektong tumutugma sa isang string sa string pool. Iyon ay, kung isusulat natin ang sumusunod na code:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       String s3 = new String("CodeGym is the best website for learning Java!");
   }
}
Sa memorya, ganito ang hitsura:
Mga katumbas at paghahambing ng string - 4
At sa tuwing gagawa ka ng bagong bagay gamit ang new , isang bagong lugar ng memorya ang inilalaan, kahit na ang teksto sa loob ng bagong string ay pareho! Mukhang nalaman namin ang == operator. Ngunit paano ang aming bagong kakilala, ang equals() na pamamaraan?

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1.equals(s2));
   }
}
Output ng console: true Interesting. Kami ay tiyak na ang s1 at s2 ay tumuturo sa iba't ibang bahagi ng memorya. Ngunit ang equals() na pamamaraan ay nagsasabi pa rin sa amin na sila ay pantay. Bakit? Tandaan na sinabi namin dati na ang equals() na pamamaraan ay maaaring ma-override upang ihambing ang mga bagay gayunpaman gusto namin? Iyon lang ang ginawa nila sa String class. Ino-override nito ang equals()paraan. At sa halip na ihambing ang mga sanggunian, inihahambing nito ang pagkakasunud-sunod ng mga character sa mga string. Kung pareho ang teksto, hindi mahalaga kung paano ginawa ang mga ito o kung saan sila naka-imbak: kung sa string pool o isang hiwalay na lugar ng memorya. Magiging totoo ang resulta ng paghahambing. Siyanga pala, hinahayaan ka ng Java na magsagawa ng mga case-insensitive na paghahambing ng string. Karaniwan, kung ang isa sa mga string ay may lahat ng malalaking titik, kung gayon ang resulta ng paghahambing ay magiging mali:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CODEGYM IS THE BEST WEBSITE FOR LEARNING JAVA!");
       System.out.println(s1.equals(s2));
   }
}
Console output: false Para sa case-insensitive na mga paghahambing, ang String class ay may equalsIgnoreCase() method. Magagamit mo ito kung gusto mo lang ihambing ang pagkakasunod-sunod ng mga partikular na character sa halip na ang letter case. Halimbawa, maaaring makatulong ito kapag naghahambing ng dalawang address:

public class Main {

   public static void main(String[] args) {

       String address1 = "2311 Broadway Street, San Francisco";
       String address2 = new String("2311 BROADWAY STREET, SAN FRANCISCO");
       System.out.println(address1.equalsIgnoreCase(address2));
   }
}
Sa kasong ito, malinaw na pinag-uusapan natin ang tungkol sa parehong address, kaya makatuwirang gamitin ang equalsIgnoreCase() na pamamaraan.

Ang String.intern() na pamamaraan

Ang String class ay may isa pang nakakalito na paraan: intern() ; Direktang gumagana ang intern() method sa string pool. Kung tatawagan mo ang intern() na pamamaraan sa ilang string:
  • Sinusuri nito kung mayroong katugmang string sa string pool
  • Kung mayroon, ibinabalik nito ang reference sa string sa pool
  • Kung hindi, idaragdag nito ang string sa string pool at ibabalik ang isang reference dito.
Pagkatapos gamitin ang intern() method sa isang string reference na nakuha gamit ang new , maaari naming gamitin ang == operator upang ihambing ito sa isang string reference mula sa string pool.

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2.intern());
   }
}
Console output: true Noong inihambing namin ang mga string na ito dati nang walang intern() , mali ang resulta. Ngayon, sinusuri ng intern() na pamamaraan kung ang string na "CodeGym ay ang pinakamahusay na site para sa pag-aaral ng Java!" ay nasa string pool. Siyempre, ito ay: nilikha namin ito gamit ang

String s1 = "CodeGym is the best website for learning Java!";
Sinusuri namin kung ang s1 at ang reference na ibinalik ng s2.intern() ay tumuturo sa parehong lugar ng memorya. At siyempre, ginagawa nila :) Sa buod, kabisaduhin at ilapat ang mahalagang tuntuning ito: LAGING gamitin ang equals() na paraan upang ihambing ang mga string! Kapag naghahambing ng mga string, halos palagi naming ibig sabihin na ihambing ang kanilang mga character sa halip na mga sanggunian, mga lugar ng memorya, o anumang bagay. Ginagawa ng equals() na pamamaraan ang eksaktong kailangan mo. Upang palakasin ang iyong natutunan, iminumungkahi naming manood ka ng isang video lesson mula sa aming Java Course

Higit pang pagbabasa:

Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION