Java-sovelluksessa Merkkijono
luokka kapseloi joukon hiiltyä
. Yksinkertaistetusti, Merkkijono
on joukko merkkejä, joita käytetään sanojen, lauseiden tai minkä tahansa muun haluamasi tiedon kirjoittamiseen.
Kapselointi on yksi olio-ohjelmoinnin tehokkaimmista käsitteistä. Kapseloinnin takia sinun ei tarvitse tietää Miten merkkijono-luokka toimii; sinun tarvitsee vain tietää mitä sen käyttöliittymässä käytettäviä menetelmiä.
Kun katsot Merkkijono
luokan Java, näet kuinka taulukko hiiltyä
on koteloitu:
public String (char arvo []) {tämä (arvo, 0, arvo.pituus, nolla); }
Harkitse fyysinen esine: auto, jotta ymmärrät kapselointia paremmin. Täytyykö sinun tietää, miten auto toimii konepellin alla ajaaksesi sitä? Ei tietenkään, mutta sinun on tiedettävä, mitä auton rajapinnat tekevät: esimerkiksi kaasupoljin, jarrut ja ohjauspyörä. Jokainen näistä rajapinnoista tukee tiettyjä toimintoja: kiihdytä, jarruta, käänny vasemmalle, käänny oikealle. Sama on olio-ohjelmoinnissa.
Ensimmäinen blogini Java-haastajat -sarja esitteli menetelmän ylikuormituksen, joka on tekniikka Merkkijono
luokka käyttää laajasti. Ylikuormitus voi tehdä luokastasi todella joustavan, mukaan lukien Merkkijono
:
public String (String original) {} public String (char value [], int offset, int count) {} public String (int [] codePoints, int offset, int count) {} public String (tavua tavuja [], int offset , int pituus, String charsetName) {} // Ja niin edelleen ... ...
Sen sijaan, että yrität ymmärtää, miten Merkkijono
luokassa toimii, tämä Java Challenger auttaa sinua ymmärtämään mitä se tekee ja Miten käyttää sitä koodissasi.
Mikä on String-allas?
Merkkijono
on mahdollisesti eniten käytetty Java-luokka. Jos muistikohteeseen luotiin uusi objekti aina, kun käytimme a Merkkijono
, tuhlaisimme paljon muistia. Merkkijono
pool ratkaisee tämän ongelman tallentamalla kullekin vain yhden objektin Merkkijono
arvo, kuten alla on esitetty.

Vaikka loimme a Merkkijono
muuttuja Duke
ja Juggy
Merkkijono
s, vain kaksi objektia luodaan ja tallennetaan muistin kasaan. Katso todiste seuraavasta koodinäytteestä. (Muistakaa, että==
”Java-operaattoria käytetään vertaamaan kahta objektia ja selvittämään, ovatko ne samat.)
Merkkijono = "Juggy"; String anotherJuggy = "Juggy"; System.out.println (juggy == anotherJuggy);
Tämä koodi palautuu totta
koska nämä kaksi Merkkijono
s osoittavat samaan objektiin Merkkijono
uima-allas. Niiden arvot ovat samat.
Poikkeus: Uusi operaattori
Katsokaa nyt tätä koodia - se näyttää samanlaiselta kuin edellinen näyte, mutta siinä on ero.
Merkkijono herttua = uusi kieli ("herttua"); String anotherDuke = uusi merkkijono ("herttua"); System.out.println (herttua == anotherDuke);
Edellisen esimerkin perusteella saatat ajatella, että tämä koodi palaa totta
, mutta se on itse asiassa väärä
. Lisäämällä Uusi
operaattori pakottaa luomaan uuden Merkkijono
muistin kasaan. Siten JVM luo kaksi erilaista objektia.
Alkuperäiset menetelmät
A natiivi menetelmä Java on menetelmä, joka käännetään C-kielellä, yleensä muistin manipuloimiseksi ja suorituskyvyn optimoimiseksi.
Jousisarjat ja harjoittelumenetelmä
Voit tallentaa a Merkkijono
että Merkkijono
uima-altaassa, käytämme tekniikkaa nimeltä Merkkijono
harjoittelu. Tässä on mitä Javadoc kertoo meille työharjoittelija()
menetelmä:
/ ** * Palauttaa merkkijono-objektille kanonisen esityksen. * * Alun perin tyhjiä merkkijonoja ylläpitää yksityisesti * luokka {@code String}. * * Kun intern-menetelmää käytetään, jos pooli sisältää jo * merkkijonon, joka on yhtä suuri kuin tämä {@code String} -objekti, määritetty * {@link #equals (Object)} -menetelmän avulla, altaan merkkijono on * palasi. Muussa tapauksessa tämä {@code String} -objekti lisätään * pooliin ja viittaus tähän {@code String} -objektiin palautetaan. * * Tästä seuraa, että minkä tahansa kahden merkkijonon {@code s} ja {@code t} kohdalla * {@code s.intern () == t.intern ()} on {@code true} * jos ja vain jos { @code s.equals (t)} on {@code true}. * * Kaikki kirjaimelliset merkkijonot ja merkkijonoarvoiset vakiolausekkeet * internoidaan. Merkkijonolitraalit on määritelty * Java ™ -kielimäärityksen osassa 3.10.5. * * @ palauttaa merkkijonon, jonka sisältö on sama kuin tällä merkkijonolla, mutta on * taatusti peräisin ainutlaatuisten merkkijonojen joukosta. * @jls 3.10.5 Jousisoiton literaalit * / julkinen syntyperäinen kielisoittaja ();
työharjoittelija()
menetelmää käytetään varastointiin Merkkijono
s a: ssa Merkkijono
uima-allas. Ensinnäkin se tarkistaa, onko Merkkijono
luomasi jo olemassa poolissa. Jos ei, se luo uuden Merkkijono
altaassa. Kulissien takana, logiikka Merkkijono
poolointi perustuu Flyweight-kuvioon.
Huomaa nyt, mitä tapahtuu, kun käytämme Uusi
avainsana pakottaa luomaan kaksi Merkkijono
s:
Merkkijono herttua = uusi kieli ("herttua"); Merkkijono herttua2 = uusi merkkijono ("herttua"); System.out.println (herttua == herttua2); // Tulos on väärä tässä System.out.println (duke.intern () == duke2.intern ()); // Tulos on totta tässä
Toisin kuin edellisessä esimerkissä Uusi
avainsana, tässä tapauksessa vertailu osoittautuu totta. Tämä johtuu siitä, että työharjoittelija()
menetelmä varmistaa Merkkijono
s tallennetaan uima-altaaseen.
Yhtä menetelmä String-luokan kanssa
on yhtä suuri ()
-menetelmää käytetään varmistamaan, onko kahden Java-luokan tila sama. Koska on yhtä suuri ()
on peräisin Esine
luokka, jokainen Java-luokka perii sen. Mutta on yhtä suuri ()
Menetelmä on ohitettava, jotta se toimisi oikein. Tietysti, Merkkijono
ohittaa on yhtä suuri ()
.
Katso:
julkinen looginen arvo on yhtä suuri (Object anObject) {if (this == anObject) {return true; } if (stringin anObject-ilmentymä) {String aString = (String) anObject; if (kooderi () == aString.coder ()) {return onLatin1 ()? StringLatin1.equals (arvo, aString.value): StringUTF16.equals (arvo, aString.value); }} return false; }
Kuten näette, Merkkijono
luokan arvon on oltava on yhtä suuri ()
eikä objektiviittausta. Ei ole väliä, onko objektiviite erilainen; valtion tila Merkkijono
verrataan.
Yleisimmät merkkijonomenetelmät
On vain yksi viimeinen asia, joka sinun on tiedettävä ennen Merkkijono
vertailuhaaste. Harkitse näitä yleisiä menetelmiä Merkkijono
luokka:
// Poistaa välilyönnit reunaviivasta () // Hakee alimerkin indeksoimalla alimerkkijonon (int beginIndex, int endIndex) // Palauttaa merkkijonon merkkien pituuden () // Korvaa merkkijonon, regexiä voidaan käyttää. aizstaaKaikki (merkkijonon regex, merkkijonon vaihto) // Tarkista, onko merkkijonossa määritetty CharSequence sisältää (CharSequences)
Ota String-vertailuhaaste!
Kokeillaan, mitä olet oppinut Merkkijono
luokan nopea haaste.
Vertaile tähän haasteeseen useita Merkkijono
s käyttämällä tutkittuja käsitteitä. Katsoessasi alla olevaa koodia voitko määrittää kunkin lopullisen arvon tuloksia muuttuja?
public class ComparisonStringChallenge {public static void main (String ... doYourBest) {String result = ""; tulos + = "voimakas koodi" .trim () == "tehokas koodi"? "0": "1"; tulos + = "FlexibleCode" == "FlexibleCode"? "2": "3"; tulos + = uusi merkkijono ("doYourBest") == uusi merkkijono ("doYourBest")? "4": "5"; tulos + = uusi merkkijono ("noBugsProject"). on yhtä suuri ("noBugsProject")? "6": "7"; tulos + = uusi merkkijono ("breakYourLimits"). harjoittelija () == uusi merkkijono ("breakYourLimits"). harjoittelija ()? "8": "9"; System.out.println (tulos); }}
Mikä tulos edustaa tulosmuuttujan lopullista arvoa?
A: 02468
B: 12469
C: 12579
D.: 12568
Tarkista vastauksesi täältä.
Mitä juuri tapahtui? Merkkijonon käyttäytymisen ymmärtäminen
Koodin ensimmäisellä rivillä näemme:
tulos + = "voimakas koodi" .trim () == "tehokas koodi"? "0": "1";
vaikkakin Merkkijono
on sama jälkeen trimmata()
menetelmää käytetään, Merkkijono
"Tehokas koodi"
oli erilainen alussa. Tässä tapauksessa vertailu on väärä
, koska kun trimmata()
menetelmä poistaa välilyöntejä rajoilta se pakottaa luomaan uuden Merkkijono
uuden operaattorin kanssa.
Seuraavaksi näemme:
tulos + = "FlexibleCode" == "FlexibleCode"? "2": "3";
Ei mitään mysteeriä täällä Merkkijono
s ovat samat Merkkijono
uima-allas. Tämä vertailu palaa totta
.
Seuraavaksi meillä on:
tulos + = uusi merkkijono ("doYourBest") == uusi merkkijono ("doYourBest")? "4": "5";
Käyttämällä Uusi
varattu avainsana pakottaa luomaan kaksi uutta Merkkijono
s riippumatta siitä, ovatko he samanarvoisia vai ei. Tässä tapauksessa vertailu on väärä
vaikka Merkkijono
arvot ovat samat.
Seuraava on:
tulos + = uusi merkkijono ("noBugsProject"). on yhtä suuri ("noBugsProject")? "6": "7";
Koska olemme käyttäneet on yhtä suuri ()
menetelmä, arvo Merkkijono
verrataan eikä objektin esiintymää. Siinä tapauksessa ei ole väliä, ovatko objektit erilaisia, koska arvoa verrataan. Tämä vertailu palaa totta
.
Lopuksi meillä on:
tulos + = uusi merkkijono ("breakYourLimits"). harjoittelija () == uusi merkkijono ("breakYourLimits"). harjoittelija ()? "8": "9";
Kuten olet aiemmin nähnyt, työharjoittelija()
menetelmä asettaa Merkkijono
että Merkkijono
uima-allas. Molemmat Merkkijono
s osoittavat samaan kohteeseen, joten tässä tapauksessa vertailu on totta
.
Video-haaste! Merkkijonojen virheenkorjaus
Virheenkorjaus on yksi helpoimmista tavoista hyödyntää ohjelmointikonsepteja täysin ja parantaa samalla koodiasi. Tässä videossa voit seurata mukana, kun minä virheenkorjaan ja selitän Java Strings -haasteen:
Merkkijonojen yleiset virheet
Voi olla vaikea tietää, ovatko kaksi Merkkijono
s osoittavat samaan kohteeseen, varsinkin kun Merkkijono
s sisältävät saman arvon. Se auttaa muistamaan, että varatun avainsanan käyttö Uusi
johtaa aina uuden objektin luomiseen muistiin, vaikka arvot olisivat samat.
Käyttämällä Merkkijono
menetelmiä vertailla Esine
viitteet voivat myös olla hankalia. Tärkeintä on, jos menetelmä muuttaa jotain Merkkijono
, objektiviitteet ovat erilaiset.
Muutama esimerkki selventämiseksi:
System.out.println ("herttua" .trim () == "herttua" .trim ()) ;;
Tämä vertailu on totta, koska trimmata()
menetelmä ei luo uutta Merkkijono
.
System.out.println ("herttua" .trim () == "herttua" .trim ());
Tässä tapauksessa ensimmäinen trimmata()
menetelmä luo uuden Merkkijono
koska menetelmä suorittaa toimintansa, joten viitteet ovat erilaiset.
Lopuksi, milloin trimmata()
toteuttaa toimintansa, se luo uuden Merkkijono
:
// Trimmimenetelmän toteutus String-luokassa uusi String (Arrays.copyOfRange (val, index, index + len), LATIN1);
Mitä muista jousista
Merkkijono
s ovat muuttumattomia, joten aMerkkijono
Tilaa ei voi muuttaa.- Muistin säästämiseksi JVM pitää
Merkkijono
s a: ssaMerkkijono
uima-allas. Kun uusiMerkkijono
luodaan, JVM tarkistaa sen arvon ja osoittaa sen olemassa olevaan objektiin. Jos ei oleMerkkijono
kun tämä arvo on poolissa, JVM luo uudenMerkkijono
. - Käyttämällä
==
operaattori vertaa objektiviittausta. Käyttämälläon yhtä suuri ()
- menetelmä vertaaMerkkijono
. Samaa sääntöä sovelletaan kaikkiin objekteihin. - Kun käytät
Uusi
operaattori, uusiMerkkijono
luodaanMerkkijono
uima-allas, vaikka siellä olisiMerkkijono
samalla arvolla.
Vastausavain
Vastaus tähän Java-haastajaan on vaihtoehto D. Tulos olisi 12568
.
Tämän tarinan "String Comparons in Java" julkaisi alun perin JavaWorld.