Užitočné tipy

Java Challengers # 2: Porovnanie reťazcov

Pin
Send
Share
Send
Send


Operátor == kontroluje referencie, nie hodnoty. To znamená, že kontroluje, či porovnávané prvky sú rovnakým objektom. Ak dve premenné reťazca ukazujú na rovnaký objekt v pamäti, porovnanie sa vráti na true. Inak nepravdivé:

Tu sú literály internalizované kompilátorom a teda odkazujú na ten istý objekt:

Vyššie uvedené premenné reťazca ukazujú na rôzne objekty:

Vyššie uvedené premenné reťazca tiež odkazujú na rôzne objekty.

Operátor ‘== 'neporovnáva dva reťazce Java, ale iba odkazy, na ktoré sa vzťahujú.

Metóda String sa rovná ()

V Java sa porovnávanie reťazcov rovná pôvodnému obsahu reťazca. Vracia hodnotu true, ak je parametrom objekt String, ktorý je rovnakým reťazcom znakov ako objekt:

Ak potrebujete skontrolovať, či dva riadky majú rovnakú hodnotu, môžete použiť Objects.equals ().

String sa rovnáIgnoreCase

Metóda equalsIgnoreCase () vykonáva lexikograficky porovnávanie reťazcov v jazyku Java, pričom ignoruje rozdiely medzi prípadmi. Pravda sa vracia, iba ak je argument objektom String, ktorý predstavuje rovnakú postupnosť znakov ako objekt. Ak potrebujete skontrolovať reťazce z hľadiska nerozlišovania veľkých a malých písmen, je lepšie použiť metódu equalsIgnoreCase triedy String.

Porovnanie metódy reťazcovTo ()

Metóda CompareTo () sa používa, keď potrebujete lexikograficky určiť poradie reťazcov. Porovnáva hodnoty char rovnakým spôsobom ako metóda equals (). Ak sa dva riadky presne zhodujú, metóda CompareTo () vráti 0 (výsledok = 0). Pri porovnávaní dvoch reťazcov Java vráti kladné celé číslo (výsledok> 0), ak prvý objekt reťazca nasleduje za druhým reťazcom. Metóda CompareTo () vráti negatívny výsledok (výsledok), ak prvý objekt String predchádza druhému riadku:

Táto publikácia je prekladom článku „Porovnanie reťazcov v jazyku Java“, ktorý pripravil priateľský tím projektu Internet technology.ru

Čo je to reťazec?

Trieda String je pravdepodobne najbežnejšie používanou triedou v jazyku Java. Ak vytvoríme nový objekt v dynamickej pamäti (hromadu pamäte) zakaždým, keď použijeme String, stratíme veľa pamäte. Fond String tento problém rieši uložením iba jedného objektu pre každú hodnotu riadku.

Čiary v rade riadkov

Aj keď sme vytvorili niekoľko premenných typu String s hodnotami Duke a Juggy, iba dva objekty sú vytvorené a uložené v dynamickej pamäti (halda). Dôkaz nájdete v nasledujúcom príklade kódu. (Pripomeňme, že v jazyku Java sa operátor „==“ používa na porovnanie dvoch objektov a na určenie, či ten istý objekt je rovnaký alebo nie.)

Tento kód sa vráti ako true, pretože dve premenné reťazca smerujú na rovnaký objekt v oblasti reťazcov. Ich význam je rovnaký.

Výnimkou je nový operátor.

Teraz sa pozrite na tento kód - vyzerá podobne ako v predchádzajúcom príklade, ale je tu rozdiel.

Na základe predchádzajúceho príkladu si môžete myslieť, že tento kód sa vráti pravdivý, ale nie je. Pridanie nového operátora vytvorí nový objekt String v pamäti. JVM tak vytvorí dva rôzne objekty.

Natívne metódy v Jave sú metódy, ktoré sa zostavia pomocou jazyka C, zvyčajne s cieľom spravovať pamäť a optimalizovať výkon.

Reťazcové bazény a metóda intern ()

Na ukladanie riadkov do fondu sa nazýva metóda string interning (String interning).

Toto je to, čo nám hovorí Javadoc o metóde intern ():

Metóda intern () sa používa na ukladanie reťazcov do oblasti reťazcov. Najprv skontroluje, či vo fonde existuje už existujúci riadok. Ak nie, vytvorí nový riadok v oblasti. Logika oblasti riadkov je založená na vzore Flyweight.

Teraz si všimnite, čo sa stane, keď použijeme nové na vytvorenie dvoch riadkov:

Na rozdiel od predchádzajúceho príkladu s novým kľúčovým slovom sa porovnanie v tomto prípade vráti na hodnotu true. Dôvodom je, že použitie metódy intern () zaisťuje, že sa reťazec nachádza v oblasti.

Rovnaká metóda v triede String

Metóda equals () sa používa na kontrolu, či sú dve triedy rovnaké alebo nie. Pretože equals () sa nachádza v triede Object, dedí ju každá trieda Java. Aby však mohla metóda equals () fungovať správne, musí byť prepísaná. Reťazec sa samozrejme rovná ().

Ako vidíte, hodnota triedy String sa porovnáva pomocou rovníc (), a nie prostredníctvom odkazu na objekt. Nezáleží na tom, či sú odkazy na objekty rôzne, stavy sa porovnajú.

Vyriešte problém porovnávania reťazcov

Pozrime sa, čo ste sa naučili o triede String, vyriešením malej hádanky.

V tejto úlohe porovnávate niekoľko riadkov pomocou konceptov, ktoré ste sa naučili. Pri pohľade na kód uvedený nižšie môžete určiť hodnotu každého výsledku premennej?

Aký bude záver?

Správna odpoveď je uvedená na konci článku.

Čo sa stalo teraz? Pochopenie správania sa reťazcov

V prvom riadku vidíme:

V tomto prípade je výsledok nepravdivý, pretože keď metóda trim () odstráni medzery, vytvorí nový reťazec pomocou nového operátora.

Nie je tu žiadne tajomstvo, riadky sú rovnaké v rade riadkov. Toto porovnanie je pravdivé.

Použitie nových vedie k vytvoreniu dvoch nových riadkov a nezáleží na tom, či sú ich hodnoty rovnaké alebo nie. V takom prípade bude porovnanie nepravdivé, aj keď sú hodnoty rovnaké.

Pretože sme použili metódu equals (), hodnota reťazca sa porovná, nie inštancia objektu.

V tomto prípade nezáleží na tom, či sú rôzne objekty alebo nie, pretože sa porovnáva hodnota. Výsledok je pravdivý.

Nakoniec máme:

Ako ste už videli, metóda intern () vkladá reťazec do oblasti reťazcov. Obe čiary smerujú na ten istý objekt, takže v tomto prípade je to pravda.

Bežné chyby reťazca

Môže byť ťažké určiť, či dva riadky odkazujú na ten istý objekt alebo nie, najmä ak tieto riadky obsahujú rovnakú hodnotu. Je užitočné si uvedomiť, že použitie nového vždy vedie k vytvoreniu nového objektu v pamäti, aj keď sú hodnoty reťazca rovnaké.

Použitie metód String na porovnanie odkazov na objekty môže byť tiež zložité. Zvláštnosťou je, že ak metóda zmení niečo v riadku, potom budú rôzne odkazy na objekty.

Niekoľko príkladov, ktoré vám pomôžu objasniť:

Toto porovnanie bude platiť, pretože metóda trim () nevytvorí nový riadok.

V tomto prípade metóda prvého trim () vygeneruje nový riadok, pretože metóda vykoná svoju prácu, a preto sa odkazy budú líšiť.

Nakoniec, keď funkcia trim () vykonáva svoju prácu, vytvorí nový riadok:

Čo si musíte pamätať o strunách

Riadky nie sú zameniteľné, takže stav riadkov nie je možné zmeniť.

Aby sa ušetrila pamäť, JVM ukladá reťazce do oblasti reťazcov. Pri vytváraní nového riadku JVM skontroluje jeho hodnotu a ukazuje na existujúci objekt. Ak oblasť nemá riadok s touto hodnotou, JVM vytvorí nový riadok.

Operátor "==" porovnáva odkazy na objekty. Metóda equals () porovnáva hodnoty reťazca. Rovnaké pravidlo bude platiť pre všetky objekty.

Pri použití nového operátora sa v halde vytvorí nový riadok.

Odpoveď na tento problém je D. Záver bude 12568.

Popis problému

Ako porovnať dva riadky?

Nasledujúci príklad porovnáva dva reťazce pomocou metód CompareTo (String), CompareToIgnoreCase (String) a CompareTo (Object String) triedy string (Class String), ktoré vracajú rozdiel ASCII prvých nepárnych znakov porovnávaných reťazcov.

Získame nasledujúci výsledok:

Ako správne porovnávať reťazce v jazyku Java?: 3 komentáre

Je zvláštne, že ak vytvoríte čiary nie cez nové, ale jednoducho im priradíte rovnaké hodnoty, budú odkazovať na jeden objekt
String str1 = "myString",
String str2 = "myString", System.out.println (str1 == str2),
výsledok bude pravdivý. Neviem prečo, ale napriek tomu) Mb, ktorý vám vysvetlí ... Môže byť triviálna úspora pamäte?

To je pravda. V Jave môžu byť reťazce v závislosti od spôsobu ich vytvorenia umiestnené do fondu alebo jednoducho vyhodené do hromady. Pri vytváraní pomocou úvodzoviek sa do oblasti vkladajú reťazce a pred vytvorením sa skontroluje, či sa v reťazci už nenašiel taký reťazec? Ak je k dispozícii, vráti sa iba odkaz naň. Odtiaľ získame odkazy na ten istý objekt. A áno, šetrí to pamäť. Je potrebné si uvedomiť, že sú ukončené reťazce v jazyku Java, čo znamená, že odkaz na jeden objekt reťazca z rôznych miest nás neohrozuje.
String s1 = "ahoj",
String s2 = "ahoj",
System.out.println (s1 == s2),
s1 + = ", priateľ!",
System.out.println (s1 == s2),
System.out.println ("s1:" + s1),
System.out.println ("s2:" + s2),
záver:
pravdivý
nepravdivý
s1: ahoj, kamoš!
s2: ahoj

To znamená, že s každou zmenou sa vytvorí nový riadok, ako to chápem, a ten starý visí v pamäti, až kým ho jeho zberateľ odpadu nevyčistí? Je to škoda, keď máte slučku na viac ako 9000 iteráciách, v ktorých sa s reťazcom manipuluje

Pin
Send
Share
Send
Send