JavaRush /Java Blog /Random-TL /Katumbas sa Java at paghahambing ng String - Paghahambing...

Katumbas sa Java at paghahambing ng String - Paghahambing ng string

Nai-publish sa grupo
Kamusta! Ngayon ay pag-uusapan natin ang tungkol sa isang napakahalaga at kawili-wiling paksa, ibig sabihin, ang paghahambing ng mga bagay sa bawat isa ay katumbas ng() sa Java. At sa katunayan, sa anong mga kaso sa Java ang Object A ay magiging katumbas ng Object B ? Katumbas at paghahambing ng string - 1Subukan 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
Okay, stop. Bakit, sa katunayan, ang dalawang kotse na ito ay hindi pantay? Binigyan namin sila ng parehong mga katangian, ngunit ang resulta ng paghahambing ay mali. Simple lang ang sagot. Ang operator ==ay hindi naghahambing ng mga katangian ng mga bagay, ngunit ang mga link. Kahit na ang dalawang bagay ay may 500 magkaparehong katangian, mali pa rin ang resulta ng paghahambing. Pagkatapos ng lahat, car1tumuturo ang mga link car2 sa dalawang magkaibang bagay , sa dalawang magkaibang address. Isipin ang isang sitwasyon sa paghahambing ng mga tao. Marahil ay may isang tao sa mundo na may parehong pangalan, kulay ng mata, edad, taas, kulay ng buhok, atbp. Ibig sabihin, magkatulad kayo sa maraming paraan, ngunit hindi pa rin kayo kambal, at lalo na hindi ang parehong tao. Katumbas at paghahambing ng string - 2Ang operator ay naglalapat ng humigit-kumulang sa parehong lohika ==kapag ginamit namin ito upang ihambing ang dalawang bagay. Ngunit paano kung kailangan mo ng ibang lohika sa iyong programa? Halimbawa, kung ginagaya ng iyong programa ang pagsusuri ng DNA. Dapat niyang ihambing ang DNA code ng dalawang tao at matukoy na sila ay kambal.
public class Man {

   int 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 == man2);
   }
}
Output ng console:

false
Ito ay lohikal na ang resulta ay pareho (pagkatapos ng lahat, wala kaming binago), ngunit ngayon ay hindi kami masaya dito! Sa katunayan, sa totoong buhay, ang pagsusuri sa DNA ay isang daang porsyentong garantiya na kambal ang kaharap natin. Ngunit ==iba ang sinasabi sa amin ng aming programa at operator. Paano natin mababago ang pag-uugaling ito at masigurado na kung magkatugma ang mga pagsusuri sa DNA, maglalabas ang programa ng tamang resulta? Para sa layuning ito, nilikha ang isang espesyal na pamamaraan sa Java - equals() .

Equals() Method sa Java

Tulad ng pamamaraang toString()tinalakay natin kanina, ang equals() ay kabilang sa klase, Objectang pinakamahalagang klase sa Java, kung saan nagmula ang lahat ng iba pang klase. Gayunpaman, ang equals() mismo ay hindi magbabago sa pag-uugali ng aming programa sa anumang paraan:
public class Man {

   String dnaCode;

   public static void main(String[] args) {

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

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

       System.out.println(man1.equals(man2));
   }
}
Output ng console:

false
Eksaktong parehong resulta, kaya bakit kailangan ang pamamaraang ito? :/ Simple lang. Ang katotohanan ay ngayon ay ginamit namin ang pamamaraang ito dahil ito ay ipinatupad sa klase mismo Object. At kung pupunta tayo sa code ng klase Objectat titingnan kung paano ipinatupad ang pamamaraang ito dito at kung ano ang ginagawa nito, makikita natin:
public boolean equals(Object obj) {
   return (this == obj);
}
Ito ang dahilan kung bakit hindi nagbabago ang ugali ng ating programa! Sa loob ng equals() na pamamaraan ng klase Objectay matatagpuan ang parehong paghahambing ng sanggunian, ==. Ngunit ang trick ng pamamaraang ito ay maaari nating i-override ito. Ang ibig sabihin ng overriding ay ang pagsulat ng iyong sariling equals() na pamamaraan sa aming klase Manat ginagawa itong kumilos sa paraang gusto namin! Ngayon hindi kami nasisiyahan na ang tseke ay man1.equals(man2)mahalagang ginagawa ang parehong bagay bilang 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
Isang ganap na kakaibang resulta! Sa pamamagitan ng pagsusulat ng sarili naming equals() na pamamaraan sa halip na ang pamantayan, nakamit namin ang tamang pag-uugali: ngayon kung ang dalawang tao ay may parehong DNA code, sasabihin sa amin ng programa: "Ang pagsusuri ng DNA ay nagpakita na sila ay kambal" at nagbabalik ng totoo! Sa pamamagitan ng pag-override sa equals() na pamamaraan sa iyong mga klase, madali mong magagawa ang kinakailangang lohika ng paghahambing ng object. Nahawakan namin ang paghahambing ng mga bagay sa mga pangkalahatang tuntunin lamang. Magkakaroon pa rin tayo ng isang hiwalay na malaking lektura sa paksang ito sa hinaharap (maaari mo itong basahin nang mabilis ngayon, kung interesado).

Paghahambing ng string sa Java - Paghahambing ng string

Bakit namin tinatrato ang mga paghahambing ng string nang hiwalay sa lahat ng iba pa? Well, sa katunayan, ang mga linya sa programming ay isang buong magkaibang kuwento. Una, kung kukunin mo ang lahat ng mga programang Java na isinulat ng sangkatauhan, mga 25% ng mga bagay sa mga ito ay binubuo ng mga ito. Samakatuwid, ang paksang ito ay napakahalaga. Pangalawa, ang proseso ng paghahambing ng mga string ay talagang naiiba sa iba pang mga bagay. Tingnan natin ang isang simpleng halimbawa:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1 == s2);
   }
}
Output ng console:

false
Pero bakit false? Ang mga linya ay eksaktong pareho, salita sa salita :/ Maaari mong ipagpalagay: ito ay dahil ang operator == ay nagkukumpara ng mga sanggunian! Pagkatapos ng lahat, mayroon s1silang s2iba't ibang mga address sa memorya. Kung naisip mo ang ideyang ito, gawin nating muli ang ating halimbawa:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = "JavaRush is the best site to learn Java!";
       System.out.println(s1 == s2);
   }
}
Ngayon mayroon na rin kaming dalawang link, ngunit ang resulta ay nagbago sa kabaligtaran: Console output:

true
Ganap na nalilito? :) Alamin natin ito. Ang operator ==ay aktwal na naghahambing ng mga address sa memorya. Palaging gumagana ang panuntunang ito at hindi na kailangang pagdudahan ito. Nangangahulugan ito na kung s1 == s2nagbabalik ito ng totoo, ang dalawang string na ito ay may parehong address sa memorya. At totoo nga! Oras na para maging pamilyar sa isang espesyal na lugar ng memorya para sa pag-iimbak ng mga string - ang string pool ( String pool) Katumbas at paghahambing ng string - 3Ang string pool ay isang lugar para sa pag-iimbak ng lahat ng mga halaga ng string na iyong nilikha sa iyong programa. Para saan ito nilikha? Tulad ng nabanggit kanina, ang mga string ay tumatagal ng isang malaking bahagi ng lahat ng mga bagay. Sa anumang malaking programa, maraming linya ang nilikha. Upang makatipid ng memorya, ito ang kailangan String Pool- isang linya na may teksto na kailangan mo ay inilalagay doon, at sa hinaharap, ang mga bagong nilikha na link ay tumutukoy sa parehong lugar ng memorya, hindi na kailangang maglaan ng karagdagang memorya sa bawat oras. Sa bawat oras na sumulat ka String = “........”, sinusuri ng programa kung mayroong isang linya na may ganoong teksto sa string pool. Kung mayroon man, hindi gagawa ng bago. At ang bagong link ay ituturo sa parehong address sa string pool kung saan naka-imbak ang string na ito. Samakatuwid, kapag nagsulat kami sa programa
String s1 = "JavaRush is the best site to learn Java!";
String s2 = "JavaRush is the best site to learn Java!";
ang link s2ay eksaktong tumuturo sa parehong lugar bilang s1. Ang unang utos ay lumikha ng isang bagong linya sa string pool na may tekstong kailangan namin, at pagdating sa pangalawa, tinukoy lang nito ang parehong lugar ng memorya bilang s1. Maaari kang gumawa ng hindi bababa sa 500 higit pang mga linya na may parehong teksto, ang resulta ay hindi magbabago. Tumigil ka. Ngunit bakit hindi gumana ang halimbawang ito para sa atin kanina?
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1 == s2);
   }
}
Sa tingin ko, intuitively, hulaan mo na kung ano ang dahilan :) Subukan mong hulaan bago magbasa pa. Makikita mong magkaiba ang pagkakalikha ng dalawang linyang ito. Ang isa ay sa tulong ng operator new, at ang pangalawa ay wala nito. Ito talaga ang dahilan. Ang bagong operator, kapag lumilikha ng isang bagay, ay puwersahang naglalaan ng isang bagong lugar sa memorya para dito . At ang linyang nilikha gamit ang new, ay hindi nagtatapos sa String Pool: ito ay nagiging isang hiwalay na bagay, kahit na ang teksto nito ay eksaktong kapareho ng parehong linya mula sa String Pool'a. Iyon ay, kung isusulat natin ang sumusunod na code:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = "JavaRush is the best site to learn Java!";
       String s3 = new String("JavaRush is the best site to learn Java!");
   }
}
Sa memorya ito ay magiging ganito: Katumbas at paghahambing ng string - 4At sa tuwing may bagong bagay na nilikha, newisang bagong lugar ang ilalaan sa memorya, kahit na ang teksto sa loob ng mga bagong linya ay pareho! Mukhang inayos namin ang operator ==, ngunit paano ang aming bagong kaibigan - ang equals() na pamamaraan?
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1.equals(s2));
   }
}
Output ng console:

true
Interesting. Alam namin nang eksakto kung ano s1at s2tumuturo sa iba't ibang mga lugar sa memorya. Ngunit, gayunpaman, ang equals() na pamamaraan ay nagsasabi na sila ay pantay. Bakit? Tandaan, sa itaas sinabi namin na ang equals() na pamamaraan ay maaaring ma-override sa iyong klase upang maihambing nito ang mga bagay sa paraang kailangan mo? Iyon ang ginawa nila sa klase String. Mayroon itong overridden equals() na pamamaraan. At hindi ito naghahambing ng mga link, ngunit sa halip ang pagkakasunud-sunod ng mga character sa mga string. At kung ang teksto sa mga string ay pareho, hindi mahalaga kung paano ito nilikha at kung saan sila naka-imbak: sa string pool, o sa isang hiwalay na lugar ng memorya. Magiging totoo ang resulta ng paghahambing. Sa pamamagitan ng paraan, pinapayagan ka ng Java na ihambing nang tama ang mga string sa isang case-insensitive na paraan. Sa isang normal na sitwasyon, kung isusulat mo ang isa sa mga linya, halimbawa, sa mga cap, ang resulta ng paghahambing ay magiging mali:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JAVARUSH - ЛУЧШИЙ САЙТ ДЛЯ ИЗУЧЕНИЯ JAVA!");
       System.out.println(s1.equals(s2));
   }
}
Output ng console:

false
Para sa kasong ito, ang klase Stringay may pamamaraan equalsIgnoreCase(). Kung ang pangunahing bagay sa iyong paghahambing ay ang pagkakasunud-sunod ng mga partikular na character, at hindi ang kanilang kaso, maaari mo itong gamitin. Halimbawa, magiging kapaki-pakinabang ito kapag naghahambing ng dalawang email address:
public class Main {

   public static void main(String[] args) {

       String address1 = "Moscow, Academician Korolev street, 12";
       String address2 = new String("Г. МОСКВА, УЛ. АКАДЕМИКА КОРОЛЕВА, ДОМ 12");
       System.out.println(address1.equalsIgnoreCase(address2));
   }
}
Sa kasong ito, malinaw na pinag-uusapan natin ang tungkol sa parehong address, kaya ang paggamit ng pamamaraan equalsIgnoreCase()ay magiging tamang desisyon.

String.intern() na pamamaraan

Ang klase Stringay may isa pang nakakalito na paraan - intern(); intern()Direktang gumagana ang pamamaraan sa String Pool'om. Kung tatawag ka ng isang paraan intern()sa isang string, ito ay:
  • Tinitingnan kung may string na may ganitong text sa string pool
  • Kung mayroon, magbabalik ng link dito sa pool
  • Kung hindi, naglalagay ito ng linya na may ganitong text sa string pool at nagbabalik ng link dito.
Sa pamamagitan ng paglalapat ng pamamaraan intern()sa string reference na nilikha sa pamamagitan ng bago, maaari nating ihambing ito sa string reference mula sa String Pool'a sa pamamagitan ng ==.
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1 == s2.intern());
   }
}
Output ng console:

true
Dati, kapag inihambing namin ang mga ito nang walang intern(), mali ang resulta. Ngayon ay sinuri ng pamamaraan intern()kung mayroong isang linya na may tekstong "JavaRush - ang pinakamahusay na site para sa pag-aaral ng Java!" sa string pool. Siyempre nandoon ito: nilikha namin ito noong isinulat namin
String s1 = "JavaRush is the best site to learn Java!";
Sinuri na ang sanggunian s1at ang sanggunian na ibinalik ng pamamaraan s2.intern()ay tumuturo sa parehong lugar sa memorya, at, siyempre, ginagawa nila :) Upang ibuod, tandaan at gamitin ang pangunahing panuntunan: Upang ihambing ang mga string, LAGING gumamit ng katumbas() paraan! Kapag naghahambing ng mga string, halos palagi mong ibig sabihin ang paghahambing ng kanilang teksto, hindi mga link, mga lugar ng memorya, at iba pa. Ginagawa ng equals() na pamamaraan kung ano mismo ang kailangan mo. Narito ang ilang link para makapag-aral ka nang mag-isa:
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION