Programování

Porovnání řetězců v Javě

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.

Rafael Chinelato Del Nero

Ačkoli jsme vytvořili Tětiva proměnná pro Vévoda a JuggyTětivas, 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ětivas 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ětivas 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ětivas:

 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ětivas 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ětivapouží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ětivajsou 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ětivas, 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ětivas 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ětivas směřují na stejný objekt, zvláště když Tětivaobsahují 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ětivajsou neměnné, takže a TětivaStav nelze změnit.
  • Pro zachování paměti JVM uchovává Tětivas v a Tě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á hodnotu Tětiva. Pro všechny objekty bude použito stejné pravidlo.
  • Při použití Nový operátor, nový Tětiva bude vytvořen v Tětiva bazén, i když tam je Tě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.

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