Programovanie

Porovnanie reťazcov v Jave

V Jave sa String trieda zapuzdruje pole char. Zjednodušene povedané, String je pole znakov, ktoré sa používajú na zostavenie slov, viet alebo iných požadovaných údajov.

Zapuzdrenie je jedným z najsilnejších konceptov v objektovo orientovanom programovaní. Kvôli zapuzdreniu nemusíte vedieť ako trieda String funguje; len to musis vediet čo metódy, ktoré sa majú použiť na jeho rozhraní.

Keď sa pozriete na String triedy v Jave, môžete vidieť, ako je pole char je zapuzdrený:

 public String (char value []) {this (value, 0, value.length, null); } 

Aby ste lepšie pochopili zapuzdrenie, pouvažujte nad fyzickým objektom: autom. Potrebujete vedieť, ako auto funguje pod kapotou, aby ste ho mohli riadiť? Samozrejme, že nie, musíte však vedieť, čo robia rozhrania automobilu: veci ako plynový pedál, brzdy a volant. Každé z týchto rozhraní podporuje určité činnosti: zrýchlenie, brzdenie, odbočenie vľavo, odbočenie vpravo. Rovnako je to aj v objektovo orientovanom programovaní.

Môj prvý blog v Vyzyvatelia Java série zaviedli metódu preťaženia, čo je technika String trieda využíva značne. Vďaka preťaženiu môžu byť vaše triedy skutočne flexibilné, vrátane String:

 public String (pôvodný reťazec) {} public String (char hodnota [], int offset, int count) {} public String (int [] codePoints, int offset, int count) {} public String (byte bytes [], int offset , int dĺžka, reťazec charsetName) {} // A tak ďalej ... ... 

Skôr ako sa snažiť pochopiť, ako String triedy, tento Java Challenger vám pomôže pochopiť čo to robí a ako použiť vo svojom kóde.

Čo je bazén String?

String je pravdepodobne najpoužívanejšou triedou v Jave. Pokiaľ bol v halde pamäte vytvorený nový objekt zakaždým, keď sme použili a String, stratili by sme veľa pamäte. The String pool tento problém rieši uložením iba jedného objektu pre každý String hodnota, ako je uvedené nižšie.

Rafael Chinelato Del Nero

Aj keď sme vytvorili a String premenná pre Vojvoda a JuggyStrings, sú na hromade pamäte vytvorené a uložené iba dva objekty. Dôkaz nájdete v nasledujúcej ukážke kódu. (Pripomeňme, že „==”Operátor v Jave sa používa na porovnanie dvoch objektov a na určenie, či sú rovnaké.)

 String juggy = "Juggy"; Reťazec anotherJuggy = "Juggy"; System.out.println (juggy == anotherJuggy); 

Tento kód sa vráti pravda pretože tí dvaja Strings smerujú na rovnaký objekt v String bazén. Ich hodnoty sú rovnaké.

Výnimka: „nový“ operátor

Teraz sa pozrite na tento kód - vyzerá podobne ako predchádzajúca ukážka, je tu však rozdiel.

 Sláčikový vojvoda = nový reťazec („vojvoda“); Reťazec anotherDuke = nový Reťazec ("vojvoda"); System.out.println (duke == anotherDuke); 

Na základe predchádzajúceho príkladu si môžete myslieť, že sa tento kód vráti pravda, ale je to tak nepravdivé. Pridáva sa Nový operátor vynúti vytvorenie nového String v hromade pamäte. Spoločný podnik JVM teda vytvorí dva rôzne objekty.

Natívne metódy

A natívna metóda v Jave je metóda, ktorá bude zostavená pomocou jazyka C, zvyčajne na účely manipulácie s pamäťou a optimalizácie výkonu.

Spoločnosti reťazcov a metóda intern ()

Na uloženie a String v String pool, používame techniku ​​tzv String interning. Tu je to, čo nám hovorí Javadoc o stážista () metóda:

 / ** * Vráti kanonické znázornenie pre objekt reťazca. * * Skupina reťazcov, pôvodne prázdna, je udržiavaná súkromne triedou * {@code String}. * * Po vyvolaní internej metódy, ak fond už obsahuje * reťazec rovný tomuto objektu {@code String}, ako je určené * metódou {@link #equals (Object)}, potom je reťazec z fondu * vrátený. V opačnom prípade bude tento objekt {@code String} pridaný do fondu * a bude vrátený odkaz na tento objekt {@code String}. * * Z toho vyplýva, že pre akékoľvek dva reťazce {@code s} a {@code t} je * {@code s.intern () == t.intern ()} {@code true} * práve vtedy, ak { @code s.equals (t)} je {@code true}. * * Všetky doslovné reťazce a konštantné výrazy s hodnotou reťazca sú * internované. Reťazcové literály sú definované v časti 3.10.5 * Jazykovej špecifikácie Java ™. * * @returns reťazec, ktorý má rovnaký obsah ako tento reťazec, ale je zaručené, * že bude zo skupiny jedinečných reťazcov. * @jls 3.10.5 String Literals * / public native String intern (); 

The stážista () metóda sa používa na ukladanie Strings v a String bazén. Najskôr overí, či String ste už vytvorili v skupine. Ak nie, vytvorí nový String v bazéne. V zákulisí logika String združovanie je založené na modeli Flyweight.

Teraz si všimnite, čo sa stane, keď použijeme Nový kľúčové slovo vynútiť vytvorenie dvoch Strings:

 Sláčikový vojvoda = nový reťazec („vojvoda“); Reťazec duke2 = nový Reťazec („duke“); System.out.println (duke == duke2); // Výsledok tu bude nepravdivý System.out.println (duke.intern () == duke2.intern ()); // Výsledok bude tu pravdivý 

Na rozdiel od predchádzajúceho príkladu s Nový kľúčové slovo, v tomto prípade sa porovnanie ukáže ako pravdivé. Je to preto, že pomocou stážista () metóda zaisťuje Strings budú uložené v bazéne.

Rovná sa metóda s triedou String

The rovná sa () metóda sa používa na overenie, či je stav dvoch tried Java rovnaký. Pretože rovná sa () je z Objekt triedy, dedí to každá trieda Java. Ale rovná sa () metóda musí byť prepísaná, aby fungovala správne. Samozrejme, String prepíše rovná sa ().

Pozri sa:

 public boolean equals (Object anObject) {if (this == anObject) {return true; } if (anObject instanceof String) {String aString = (String) anObject; if (coder () == aString.coder ()) {return isLatin1 ()? StringLatin1.equals (hodnota, aString.value): StringUTF16.equals (hodnota, aString.value); }} return false; } 

Ako vidíte, stav String hodnota triedy musí byť rovná sa () a nie odkaz na objekt. Nezáleží na tom, či je odkaz na objekt odlišný; stav štátu String sa bude porovnávať.

Najbežnejšie reťazcové metódy

Pred užitím musíte vedieť iba jednu poslednú vec String porovnávacia výzva. Zvážte tieto bežné metódy String trieda:

 // Odstráni medzery z okrajov trim () // Získa podreťazec pomocou indexov podreťazec (int beginIndex, int endIndex) // Vráti dĺžku znakov dĺžky reťazca () // Nahradí reťazec, je možné použiť regex. replaceAll (String regex, String replacement) // Overí, či je v reťazci String contains (CharSequences) zadaná CharSequence. 

Postavte sa výzve na porovnávanie reťazcov!

Poďme vyskúšať, čo ste sa o tom dozvedeli String triedy v rýchlej výzve.

Pri tejto výzve porovnáte niekoľko Stringpoužívame koncepty, ktoré sme preskúmali. Pri pohľade na kód nižšie môžete určiť konečnú hodnotu každého z nich výsledky premenná?

 public class ComparisonStringChallenge {public static void main (String ... doYourBest) {String result = ""; result + = "powerfulCode" .trim () == "powerfulCode"? "0": "1"; výsledok + = "flexibleCode" == "flexibleCode"? "2": "3"; výsledok + = nový reťazec ("doYourBest") == nový reťazec ("doYourBest")? "4": "5"; result + = new String ("noBugsProject") .equals ("noBugsProject")? "6": "7"; result + = new String ("breakYourLimits"). intern () == nový String ("breakYourLimits"). intern ()? "8": "9"; System.out.println (výsledok); }} 

Ktorý výstup predstavuje konečnú hodnotu výslednej premennej?

A: 02468

B: 12469

C.: 12579

D: 12568

Skontrolujte svoju odpoveď tu.

Čo sa práve stalo? Pochopenie reťazcového správania

V prvom riadku kódu vidíme:

 result + = "powerfulCode" .trim () == "powerfulCode"? "0": "1"; 

Napriek tomu String bude rovnaký aj po trim () metóda je vyvolaná, String„Powerfulcode“ bola na začiatku iná. V tomto prípade je porovnanie nepravdivé, pretože keď trim () metóda odstráni medzery z hraníc a vynúti vytvorenie novej String s novým operátorom.

Ďalej vidíme:

 výsledok + = "flexibleCode" == "flexibleCode"? "2": "3"; 

Žiadne tajomstvo tu nie je Stringsú rovnaké v String bazén. Toto porovnanie sa vráti pravda.

Ďalej máme:

 výsledok + = nový reťazec ("doYourBest") == nový reťazec ("doYourBest")? "4": "5"; 

Pomocou Nový Vyhradené kľúčové slovo si vynúti vytvorenie dvoch nových Strings, či sú si rovní alebo nie. V takom prípade bude porovnanie nepravdivé aj keď String hodnoty sú rovnaké.

Ďalej je:

 result + = new String ("noBugsProject") .equals ("noBugsProject")? "6": "7"; 

Pretože sme použili rovná sa () metóda, hodnota String bude sa porovnávať a nie inštancia objektu. V takom prípade nezáleží na tom, či sú objekty odlišné, pretože sa porovnáva hodnota. Toto porovnanie sa vráti pravda.

Nakoniec máme:

 result + = new String ("breakYourLimits"). intern () == nový String ("breakYourLimits"). intern ()? "8": "9"; 

Ako ste už videli, stážista () metóda kladie String v String bazén. Oboje Strings smerujú na rovnaký objekt, takže v tomto prípade je porovnanie pravda.

Video výzva! Ladenie porovnaní reťazcov

Ladenie je jedným z najjednoduchších spôsobov, ako úplne absorbovať programovacie koncepty a zároveň vylepšiť váš kód. V tomto videu môžete sledovať, kým ladím a vysvetľujem výzvu Java Strings:

Časté chyby s reťazcami

Môže byť ťažké vedieť, či dva Strings smerujú na rovnaký objekt, najmä keď Stringobsahujú rovnakú hodnotu. Pomáha to pamätať na to, že sa používa vyhradené kľúčové slovo Nový vždy vedie k vytvoreniu nového objektu v pamäti, aj keď sú hodnoty rovnaké.

Použitím String metódy na porovnanie Objekt referencie môžu byť tiež zložité. Kľúčové je, ak metóda niečo zmení v String, odkazy na objekty sa budú líšiť.

Niekoľko príkladov na objasnenie:

 System.out.println ("duke" .trim () == "duke" .trim ()) ;; 

Toto porovnanie bude pravdivé, pretože trim () metóda negeneruje nový String.

 System.out.println ("duke" .trim () == "duke" .trim ()); 

V tomto prípade prvý trim () metóda vygeneruje nový String pretože metóda vykoná svoju akciu, takže odkazy sa budú líšiť.

Konečne, keď trim () vykoná svoju akciu, vytvorí novú String:

 // Implementácia metódy trim v triede String new String (Arrays.copyOfRange (val, index, index + len), LATIN1); 

Čo si pamätať o Strunách

  • Strings sú nemenné, takže a StringStav nie je možné zmeniť.
  • Kvôli šetreniu pamäte si JVM uchováva Strings v a String bazén. Keď nový String je vytvorený, JVM skontroluje jeho hodnotu a nasmeruje ho na existujúci objekt. Ak nie je String s touto hodnotou v združení potom JVM vytvorí nový String.
  • Pomocou == operátor porovnáva referenciu na objekt. Pomocou rovná sa () metóda porovnáva hodnotu String. Rovnaké pravidlo sa bude uplatňovať na všetky objekty.
  • Pri použití Nový operátor, nový String sa vytvorí v String bazén, aj keď existuje a String s rovnakou hodnotou.

 

Odpovedať kľúč

Odpoveďou na tohto vyzývateľa Java je možnosť D. Výstup by bol 12568.

Tento príbeh, „Porovnanie reťazcov v jazyku Java“, pôvodne publikoval server JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found