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.
Aj keď sme vytvorili a String
premenná pre Vojvoda
a Juggy
String
s, 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 String
s 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 String
s 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 String
s:
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 String
s 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 String
použí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 String
sú 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 String
s, č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 String
s 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 String
s smerujú na rovnaký objekt, najmä keď String
obsahujú 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
String
s sú nemenné, takže aString
Stav nie je možné zmeniť.- Kvôli šetreniu pamäte si JVM uchováva
String
s v aString
bazén. Keď novýString
je vytvorený, JVM skontroluje jeho hodnotu a nasmeruje ho na existujúci objekt. Ak nie jeString
s touto hodnotou v združení potom JVM vytvorí novýString
. - Pomocou
==
operátor porovnáva referenciu na objekt. Pomocourovná sa ()
metóda porovnáva hodnotuString
. Rovnaké pravidlo sa bude uplatňovať na všetky objekty. - Pri použití
Nový
operátor, novýString
sa vytvorí vString
bazén, aj keď existuje aString
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.