V Javě je Tětiva
třída zapouzdřuje pole char
. Jednoduše řečeno Tětiva
je pole znaků, které se používají k sestavování slov, vět nebo jakýchkoli dalších požadovaných údajů.
Zapouzdření je jedním z nejsilnějších konceptů v objektově orientovaném programování. Kvůli zapouzdření nemusíte vědět jak třída String funguje; stačí to vědět co metody, které se použijí na jeho rozhraní.
Když se podíváte na Tětiva
třídy v Javě, můžete vidět, jak pole char
je zapouzdřený:
public String (char value []) {this (value, 0, value.length, null); }
Abyste lépe porozuměli zapouzdření, zvažte fyzický objekt: auto. Potřebujete vědět, jak auto pod kapotou pracuje, abyste s ním mohli řídit? Samozřejmě, že ne, ale musíte vědět, co dělají rozhraní automobilu: věci jako plyn, brzdy a volant. Každé z těchto rozhraní podporuje určité akce: zrychlení, brzdění, odbočení vlevo, odbočení vpravo. Totéž platí pro objektově orientované programování.
Můj první blog v Vyzyvatelé jazyka Java série zavedla metodu přetížení, což je technika Tětiva
třída používá značně. Díky přetížení mohou být vaše třídy opravdu flexibilní, včetně Tětiva
:
public String (String original) {} public String (char value [], int offset, int count) {} public String (int [] codePoints, int offset, int count) {} public String (byte bytes [], int offset , int length, String charsetName) {} // A tak dále ... ...
Spíše než se snažit pochopit, jak Tětiva
třídy, tento Java Challenger vám pomůže pochopit co to dělá a jak použít ve vašem kódu.
Co je to String Pool?
Tětiva
je možná nejpoužívanější třída v Javě. Pokud byl v haldě paměti vytvořen nový objekt pokaždé, když jsme použili a Tětiva
, ztratili bychom spoustu paměti. The Tětiva
pool tento problém řeší uložením pouze jednoho objektu pro každý Tětiva
hodnotu, jak je uvedeno níže.

Ačkoli jsme vytvořili Tětiva
proměnná pro Vévoda
a Juggy
Tětiva
s, pouze dva objekty jsou vytvořeny a uloženy v haldě paměti. Pro důkaz se podívejte na následující ukázku kódu. (Připomeňme, že „==
„Operátor v Javě se používá k porovnání dvou objektů a k určení, zda jsou stejné.)
String juggy = "Juggy"; Řetězec anotherJuggy = "Juggy"; System.out.println (juggy == anotherJuggy);
Tento kód se vrátí skutečný
protože ti dva Tětiva
s přejděte na stejný objekt v souboru Tětiva
bazén. Jejich hodnoty jsou stejné.
Výjimka: „nový“ operátor
Nyní se podívejte na tento kód - vypadá podobně jako předchozí ukázka, ale existuje rozdíl.
String duke = nový String ("vévoda"); String anotherDuke = new String ("duke"); System.out.println (vévoda == anotherDuke);
Na základě předchozího příkladu si můžete myslet, že se tento kód vrátí skutečný
, ale je to ve skutečnosti Nepravdivé
. Přidání Nový
operátor vynutí vytvoření nového Tětiva
v haldě paměti. JVM tedy vytvoří dva různé objekty.
Nativní metody
A nativní metoda v Javě je metoda, která bude kompilována pomocí jazyka C, obvykle za účelem manipulace s pamětí a optimalizace výkonu.
Řetězcové fondy a metoda intern ()
Uložení a Tětiva
v Tětiva
pool, používáme techniku zvanou Tětiva
směna. Zde nám říká Javadoc o internovat()
metoda:
/ ** * Vrátí kanonickou reprezentaci objektu řetězce. * * Skupina řetězců, původně prázdná, je soukromě udržována třídou * {@code String}. * * Když je vyvolána interní metoda, pokud fond již obsahuje * řetězec rovný tomuto objektu {@code String}, jak je určeno * metodou {@link #equals (Object)}, pak řetězec z fondu je * vrátil. Jinak bude tento objekt {@code String} přidán do fondu * a bude vrácen odkaz na tento objekt {@code String}. * * Z toho vyplývá, že pro libovolné dva řetězce {@code s} a {@code t} je * {@code s.intern () == t.intern ()} {@code true} * právě když { @code s.equals (t)} je {@code true}. * * Všechny doslovné řetězce a konstantní výrazy s hodnotou řetězce jsou * internovány. Řetězcové literály jsou definovány v části 3.10.5 * Specifikace jazyka Java ™. * * @returns řetězec, který má stejný obsah jako tento řetězec, ale je * zaručeno, že bude ze skupiny jedinečných řetězců. * @jls 3.10.5 String Literals * / public native String intern ();
The internovat()
metoda se používá k ukládání Tětiva
s v a Tětiva
bazén. Nejprve ověří, zda Tětiva
jste již vytvořili ve fondu. Pokud ne, vytvoří nový Tětiva
v bazénu. V zákulisí logika Tětiva
sdružování je založeno na vzoru muší váhy.
Nyní si všimněte, co se stane, když použijeme Nový
klíčové slovo vynutit vytvoření dvou Tětiva
s:
String duke = nový String ("vévoda"); Řetězec duke2 = nový řetězec ("vévoda"); System.out.println (duke == duke2); // Výsledek zde bude nepravdivý System.out.println (duke.intern () == duke2.intern ()); // Výsledek zde bude pravdivý
Na rozdíl od předchozího příkladu s Nový
klíčové slovo, v tomto případě se srovnání ukáže jako pravdivé. Je to proto, že pomocí internovat()
metoda zajišťuje Tětiva
s budou uloženy v bazénu.
Rovná se metoda s třídou String
The se rovná()
metoda se používá k ověření, zda je stav dvou tříd Java stejný. Protože se rovná()
je z Objekt
třídy, každá třída Java to zdědí. Ale se rovná()
metoda musí být přepsána, aby fungovala správně. Samozřejmě, Tětiva
přepíše se rovná()
.
Podívej se:
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); }} vrátit false; }
Jak vidíte, stav Tětiva
hodnota třídy musí být se rovná()
a ne odkaz na objekt. Nezáleží na tom, zda je odkaz na objekt jiný; stav státu Tětiva
budou porovnány.
Nejběžnější metody řetězce
Je tu ještě jedna poslední věc, kterou byste měli vědět, než si vezmete Tětiva
srovnávací výzva. Zvažte tyto běžné metody Tětiva
třída:
// Odstraní mezery z okrajů trim () // Získá podřetězec pomocí indexů podřetězec (int beginIndex, int endIndex) // Vrátí délku znaků String length () // Nahradí řetězec, lze použít regex. replaceAll (String regex, String replacement) // Ověří, zda je v řetězci obsahuje zadaná CharSequence (CharSequences)
Přijměte výzvu k porovnání řetězců!
Pojďme si vyzkoušet, co jste se o tom dozvěděli Tětiva
třídy v rychlé výzvě.
U této výzvy porovnáte řadu Tětiva
používáme koncepty, které jsme prozkoumali. Při pohledu na níže uvedený kód můžete určit konečnou hodnotu každého z nich Výsledek variabilní?
public class ComparisonStringChallenge {public static void main (String ... doYourBest) {String result = ""; result + = "powerfulCode" .trim () == "powerfulCode"? "0": "1"; result + = "flexibleCode" == "flexibleCode"? "2": "3"; result + = new String ("doYourBest") == new String ("doYourBest")? "4": "5"; result + = new String ("noBugsProject") .equals ("noBugsProject")? "6": "7"; result + = new String ("breakYourLimits"). intern () == new String ("breakYourLimits"). intern ()? "8": "9"; System.out.println (výsledek); }}
Který výstup představuje konečnou hodnotu výsledné proměnné?
A: 02468
B: 12469
C: 12579
D: 12568
Zkontrolujte svou odpověď zde.
Co se právě stalo? Porozumění chování řetězce
V prvním řádku kódu vidíme:
result + = "powerfulCode" .trim () == "powerfulCode"? "0": "1";
Ačkoliv Tětiva
bude stejný po trim ()
metoda je vyvolána, Tětiva
„Powerfulcode“
na začátku to bylo jiné. V tomto případě je srovnání Nepravdivé
, protože když trim ()
metoda odstraní mezery z hranic a vynutí vytvoření nového Tětiva
s novým operátorem.
Dále vidíme:
result + = "flexibleCode" == "flexibleCode"? "2": "3";
Žádné tajemství zde není Tětiva
jsou stejné v Tětiva
bazén. Toto srovnání se vrací skutečný
.
Dále máme:
result + = new String ("doYourBest") == new String ("doYourBest")? "4": "5";
Za použití Nový
vyhrazené klíčové slovo vynutí vytvoření dvou nových Tětiva
s, ať jsou si rovni nebo ne. V tomto případě bude srovnání Nepravdivé
i když Tětiva
hodnoty jsou stejné.
Další je:
result + = new String ("noBugsProject") .equals ("noBugsProject")? "6": "7";
Protože jsme použili se rovná()
metoda, hodnota Tětiva
budou porovnány a ne instance objektu. V takovém případě nezáleží na tom, zda se objekty liší, protože se porovnává hodnota. Toto srovnání se vrací skutečný
.
Konečně máme:
result + = new String ("breakYourLimits"). intern () == new String ("breakYourLimits"). intern ()? "8": "9";
Jak jste již viděli, internovat()
metoda staví Tětiva
v Tětiva
bazén. Oba Tětiva
s ukazují na stejný objekt, takže v tomto případě je srovnání skutečný
.
Video výzva! Ladění porovnání řetězců
Ladění je jedním z nejjednodušších způsobů, jak plně absorbovat programovací koncepty a zároveň vylepšit váš kód. V tomto videu můžete sledovat, zatímco ladím a vysvětluji výzvu Java Strings:
Časté chyby s řetězci
Může být obtížné zjistit, jestli dva Tětiva
s směřují na stejný objekt, zvláště když Tětiva
obsahují stejnou hodnotu. Pomáhá si to zapamatovat pomocí vyhrazeného klíčového slova Nový
vždy vede k vytvoření nového objektu v paměti, i když jsou hodnoty stejné.
Použitím Tětiva
metody k porovnání Objekt
odkazy mohou být také obtížné. Klíčem je, pokud metoda něco změní v Tětiva
, odkazy na objekty se budou lišit.
Několik příkladů k objasnění:
System.out.println ("vévoda" .trim () == "vévoda" .trim ()) ;;
Toto srovnání bude pravdivé, protože trim ()
metoda negeneruje nový Tětiva
.
System.out.println ("vévoda" .trim () == "vévoda" .trim ());
V tomto případě první trim ()
metoda vygeneruje nový Tětiva
protože metoda provede svoji akci, takže odkazy se budou lišit.
Konečně, když trim ()
provede svoji akci, vytvoří novou Tětiva
:
// Implementace metody trim ve třídě String new String (Arrays.copyOfRange (val, index, index + len), LATIN1);
Co si pamatovat o Strunách
Tětiva
jsou neměnné, takže aTětiva
Stav nelze změnit.- Pro zachování paměti JVM uchovává
Tětiva
s v aTětiva
bazén. Když novýTětiva
je vytvořen, JVM zkontroluje jeho hodnotu a nasměruje jej na existující objekt. Pokud neníTětiva
s touto hodnotou ve fondu vytvoří JVM novýTětiva
. - Za použití
==
operátor porovná odkaz na objekt. Za použitíse rovná()
metoda porovnává hodnotuTětiva
. Pro všechny objekty bude použito stejné pravidlo. - Při použití
Nový
operátor, novýTětiva
bude vytvořen vTětiva
bazén, i když tam jeTětiva
se stejnou hodnotou.
Odpovědět klíč
Odpověď na tohoto vyzývatele Java je možnost D. Výstup by byl 12568
.
Tento příběh, „Porovnání řetězců v Javě“, původně publikoval JavaWorld.