I Java er Snor
klasse indkapsler en matrix af char
. Enkelt sagt, Snor
er en række tegn, der bruges til at komponere ord, sætninger eller andre data, du ønsker.
Indkapsling er et af de mest kraftfulde begreber inden for objektorienteret programmering. På grund af indkapsling behøver du ikke vide det hvordan String-klassen fungerer; du skal bare vide det hvad metoder til brug på dens grænseflade.
Når du ser på Snor
klasse i Java, kan du se, hvordan matrixen af char
er indkapslet:
public String (char værdi []) {this (værdi, 0, værdi.længde, null); }
For at forstå indkapsling bedre, overvej et fysisk objekt: en bil. Har du brug for at vide, hvordan bilen fungerer under motorhjelmen for at køre den? Naturligvis ikke, men du behøver at vide, hvad bilens grænseflader gør: ting som gaspedal, bremser og rat. Hver af disse grænseflader understøtter visse handlinger: accelerere, bremse, drej til venstre, drej til højre. Det er det samme i objektorienteret programmering.
Min første blog i Java udfordrere serien introducerede metode overbelastning, som er en teknik Snor
klasse bruger i vid udstrækning. Overbelastning kan gøre dine klasser virkelig fleksible, herunder Snor
:
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 længde, String charsetName) {} // Og så videre ... ...
I stedet for at prøve at forstå, hvordan Snor
klasse fungerer, vil denne Java Challenger hjælpe dig med at forstå hvad det gør og hvordan at bruge det i din kode.
Hvad er en streng pool?
Snor
er muligvis den mest anvendte klasse i Java. Hvis der blev oprettet et nyt objekt i hukommelsesbunken hver gang, brugte vi en Snor
, ville vi spilde en masse hukommelse. Det Snor
pool løser dette problem ved kun at gemme et objekt til hver Snor
værdi, som vist nedenfor.
Selvom vi skabte en Snor
variabel til Hertug
og Juggy
Snor
s, kun to objekter oprettes og gemmes i hukommelsesbunken. For bevis kan du se på følgende kodeeksempel. (Husk at “==
”Operator i Java bruges til at sammenligne to objekter og afgøre, om de er ens.)
String juggy = "Juggy"; String anotherJuggy = "Juggy"; System.out.println (juggy == anotherJuggy);
Denne kode vender tilbage rigtigt
fordi de to Snor
s peger på det samme objekt i Snor
pool. Deres værdier er de samme.
En undtagelse: Den 'nye' operatør
Se nu på denne kode - den ligner den forrige prøve, men der er forskel.
String hertug = ny streng ("hertug"); String anotherDuke = ny streng ("hertug"); System.out.println (hertug == anotherDuke);
Baseret på det foregående eksempel tror du måske, at denne kode ville vende tilbage rigtigt
, men det er faktisk falsk
. Tilføjelse af ny
operatør tvinger oprettelsen af et nyt Snor
i hukommelsesbunken. Således opretter JVM to forskellige objekter.
Indfødte metoder
EN indfødte metode i Java er en metode, der vil blive sammensat ved hjælp af C-sproget, normalt med det formål at manipulere hukommelse og optimere ydeevnen.
Strengpools og metoden intern ()
At gemme en Snor
i Snor
pool, bruger vi en teknik kaldet Snor
praktikant. Her er hvad Javadoc fortæller os om praktikant ()
metode:
/ ** * Returnerer en kanonisk repræsentation for strengobjektet. * * En pool af strenge, oprindeligt tomme, vedligeholdes privat af * klassen {@code String}. * * Når internmetoden påberåbes, hvis puljen allerede indeholder en * streng svarende til dette {@code String} -objekt som bestemt af * metoden {@link #equals (Object)}, er strengen fra puljen * vendt tilbage. Ellers føjes dette {@code String} -objekt til * puljen, og en reference til dette {@code String} -objekt returneres. * * Det følger heraf, at for to strenge er {@code s} og {@code t} * {@code s.intern () == t.intern ()} {@code true} *, hvis og kun hvis { @code s.equals (t)} er {@code true}. * * Alle bogstavelige strenge og strengværdiansatte konstante udtryk er * interneret. Strengbogstaver er defineret i afsnit 3.10.5 i * Java ™ Language Specification. * * @ returnerer en streng, der har det samme indhold som denne streng, men som * garanteret kommer fra en pulje af unikke strenge. * @jls 3.10.5 String Literals * / public native String praktikant ();
Det praktikant ()
metode bruges til at gemme Snor
s i en Snor
pool. For det første kontrollerer det, om Snor
du har oprettet, findes allerede i puljen. Hvis ikke, skaber det et nyt Snor
i poolen. Bag kulisserne er logikken i Snor
pooling er baseret på Flyweight-mønsteret.
Bemærk nu, hvad der sker, når vi bruger ny
nøgleord for at tvinge oprettelsen af to Snor
s:
String hertug = ny streng ("hertug"); String duke2 = ny streng ("hertug"); System.out.println (hertug == duke2); // Resultatet vil være forkert her System.out.println (duke.intern () == duke2.intern ()); // Resultatet vil være sandt her
I modsætning til det foregående eksempel med ny
nøgleord, i dette tilfælde viser sammenligningen sig at være sand. Det skyldes, at du bruger praktikant ()
metode sikrer, at Snor
s gemmes i puljen.
Lige med metoden String-klassen
Det lige med()
metoden bruges til at verificere, om tilstanden for to Java-klasser er den samme. Fordi lige med()
er fra Objekt
klasse, hver Java-klasse arver den. Men lige med()
metoden skal tilsidesættes for at få den til at fungere korrekt. Selvfølgelig, Snor
tilsidesætter lige med()
.
Se:
public boolean er lig med (Object anObject) {if (this == anObject) {return true; } if (anObject instance of String) {String aString = (String) anObject; hvis (coder () == aString.coder ()) {return erLatin1 ()? StringLatin1.equals (værdi, aString.value): StringUTF16.equals (værdi, aString.value); }} returner falsk; }
Som du kan se, tilstanden af Snor
klasseværdi skal være lige med()
og ikke objektreferencen. Det betyder ikke noget, om objektreferencen er anderledes; tilstanden af Snor
vil blive sammenlignet.
Mest almindelige strengmetoder
Der er kun en sidste ting, du har brug for at vide, før du tager Snor
sammenligningsudfordring. Overvej disse almindelige metoder til Snor
klasse:
// Fjerner mellemrum fra kanterne trim () // Får en understreng efter indekserer understreng (int begynderIndex, int slutIndex) // Returnerer tegnlængden på strenglængden () // Erstatter streng, regex kan bruges. replaceAll (String regex, String replacement) // Kontrollerer, om der er en specificeret CharSequence i String indeholder (CharSequences)
Tag streng sammenligning udfordring!
Lad os prøve, hvad du har lært om Snor
klasse i en hurtig udfordring.
Til denne udfordring sammenligner du et antal Snor
s bruger de koncepter, vi har udforsket. Ser du på koden nedenfor, kan du bestemme den endelige værdi for hver resultater variabel?
public class ComparisonStringChallenge {public static void main (String ... doYourBest) {String result = ""; resultat + = "powerfulCode" .trim () == "powerfulCode"? "0": "1"; resultat + = "fleksibel kode" == "fleksibel kode"? "2": "3"; resultat + = ny streng ("doYourBest") == ny streng ("doYourBest")? "4": "5"; resultat + = ny streng ("noBugsProject"). lige ("noBugsProject")? "6": "7"; resultat + = ny streng ("breakYourLimits"). praktikant () == ny streng ("breakYourLimits"). praktikant ()? "8": "9"; System.out.println (resultat); }}
Hvilket output repræsenterer den endelige værdi af resultatvariablen?
EN: 02468
B: 12469
C: 12579
D: 12568
Tjek dit svar her.
Hvad skete der lige? Forståelse af strengadfærd
I den første linje i koden ser vi:
resultat + = "powerfulCode" .trim () == "powerfulCode"? "0": "1";
Selvom Snor
vil være den samme efter trimme()
metode påberåbes, Snor
“Kraftfuld kode”
var anderledes i starten. I dette tilfælde er sammenligningen falsk
, fordi når trimme()
metode fjerner mellemrum fra grænserne, det tvinger oprettelsen af et nyt Snor
med den nye operatør.
Dernæst ser vi:
resultat + = "fleksibel kode" == "fleksibel kode"? "2": "3";
Intet mysterium her Snor
s er de samme i Snor
pool. Denne sammenligning vender tilbage rigtigt
.
Dernæst har vi:
resultat + = ny streng ("doYourBest") == ny streng ("doYourBest")? "4": "5";
Bruger ny
reserveret nøgleord tvinger oprettelsen af to nye Snor
s, uanset om de er ens eller ikke. I dette tilfælde vil sammenligningen være falsk
selvom den Snor
værdier er de samme.
Næste er:
resultat + = ny streng ("noBugsProject"). lige ("noBugsProject")? "6": "7";
Fordi vi har brugt lige med()
metode, værdien af Snor
vil blive sammenlignet og ikke objektforekomsten. I så fald betyder det ikke noget, om objekterne er forskellige, fordi værdien sammenlignes. Denne sammenligning vender tilbage rigtigt
.
Endelig har vi:
resultat + = ny streng ("breakYourLimits"). praktikant () == ny streng ("breakYourLimits"). praktikant ()? "8": "9";
Som du har set før, praktikant ()
metode sætter Snor
i Snor
pool. Begge Snor
s peger på det samme objekt, så i dette tilfælde er sammenligningen rigtigt
.
Video udfordring! Fejlfinding af strengesammenligninger
Fejlfinding er en af de nemmeste måder til fuldt ud at absorbere programmeringskoncepter, samtidig med at du forbedrer din kode. I denne video kan du følge med, mens jeg fejler og forklarer Java Strings-udfordringen:
Almindelige fejl med strenge
Det kan være svært at vide, om to Snor
s peger på det samme objekt, især når Snor
s indeholder den samme værdi. Det hjælper med at huske at bruge det reserverede nøgleord ny
resulterer altid i, at der oprettes et nyt objekt i hukommelsen, selvom værdierne er de samme.
Ved brug af Snor
metoder til sammenligning Objekt
referencer kan også være vanskelige. Nøglen er, hvis metoden ændrer noget i Snor
vil objektreferencer være forskellige.
Et par eksempler, der hjælper med at afklare:
System.out.println ("hertug" .trim () == "hertug" .trim ()) ;;
Denne sammenligning vil være sand, fordi trimme()
metoden genererer ikke en ny Snor
.
System.out.println ("hertug" .trim () == "hertug" .trim ());
I dette tilfælde den første trimme()
metode genererer en ny Snor
fordi metoden udfører sin handling, så referencerne vil være forskellige.
Endelig hvornår trimme()
udfører sin handling, skaber den en ny Snor
:
// Implementering af trimmetoden i String-klassen ny String (Arrays.copyOfRange (val, index, index + len), LATIN1);
Hvad man skal huske om strenge
Snor
s er uforanderlige, så aSnor
Tilstand kan ikke ændres.- For at spare hukommelse holder JVM det
Snor
s i enSnor
pool. Når en nySnor
oprettes, kontrollerer JVM værdien og peger den på et eksisterende objekt. Hvis der ikke er nogenSnor
med denne værdi i puljen, opretter JVM en nySnor
. - Bruger
==
operatøren sammenligner objektreferencen. Brugerlige med()
metode sammenligner værdien afSnor
. Den samme regel anvendes på alle objekter. - Når du bruger
ny
operatør, en nySnor
vil blive oprettet iSnor
pool, selvom der er enSnor
med samme værdi.
Svar nøgle
Svaret på denne Java-udfordrer er Option D. Output ville være 12568
.
Denne historie, "String comparisons in Java" blev oprindeligt udgivet af JavaWorld.