Usporedbe nizova u Javi

U Javi Stringklasa enkapsulira niz char. Pojednostavljeno, Stringniz je znakova koji se koriste za sastavljanje riječi, rečenica ili bilo kojih drugih podataka koje želite.

Inkapsulacija je jedan od najsnažnijih koncepata u objektno orijentiranom programiranju. Zbog enkapsulacije ne morate znati kako funkcionira klasa String; samo trebate znati koje metode koristiti na njegovom sučelju.

Kada pogledate Stringklasu u Javi, možete vidjeti kako charje enkapsuliran niz :

 public String(char value[]) { this(value, 0, value.length, null); } 

Da biste bolje razumjeli inkapsulaciju, uzmite u obzir fizički objekt: automobil. Trebate li znati kako automobil radi ispod haube da biste ga vozili? Naravno da ne, ali morate znati što rade sučelja automobila: stvari poput gasa, kočnica i upravljača. Svako od ovih sučelja podržava određene radnje: ubrzanje, kočenje, skretanje ulijevo, skretanje udesno. Isto je i u objektno orijentiranom programiranju.

Moj prvi blog iz serije Java Challengers uveo je preopterećenje metoda, što je tehnika koju Stringklasa intenzivno koristi. Preopterećenje može vašu nastavu učiniti stvarno fleksibilnom, uključujući String:

 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) {} // And so on…... 

Umjesto da pokušava razumjeti kako Stringklasa radi, ovaj Java Challenger pomoći će vam da razumijete što radi i kako ga koristiti u vašem kodu.

Što je String pool?

Stringje vjerojatno najčešće korištena klasa u Javi. Da se svaki novi objekt stvori u memorijskoj hrpi svaki put kada bismo koristili a String, izgubili bismo puno memorije. StringBazen rješava ovaj problem pohranjivanja samo jedan predmet za svaku Stringvrijednost, kao što je prikazano u nastavku.

Rafael Chinelato Del Nero

Iako smo kreirali Stringvarijablu za Dukei JuggyString, samo se dva objekta kreiraju i pohranjuju u hrpu memorije. Za dokaz pogledajte sljedeći uzorak koda. (Sjetimo se da se ==operator “ ” u Javi koristi za usporedbu dva objekta i utvrđivanje jesu li isti.)

 String juggy = "Juggy"; String anotherJuggy = "Juggy"; System.out.println(juggy == anotherJuggy); 

Ovaj će se kôd vratiti truejer dvije Strings usmjeravaju na isti objekt u Stringspremištu. Vrijednosti su im iste.

Iznimka: Operator 'novi'

Sada pogledajte ovaj kod - izgleda slično prethodnom uzorku, ali postoji razlika.

 String duke = new String("duke"); String anotherDuke = new String("duke"); System.out.println(duke == anotherDuke); 

Na temelju prethodnog primjera, možda mislite da će se ovaj kôd vratiti true, ali zapravo je tako false. Dodavanje newoperatora prisiljava stvaranje novog Stringu hrpi memorije. Dakle, JVM će stvoriti dva različita objekta.

Izvorne metode

Porijeklom metoda u Javi je metoda koja će se sastaviti primjenom C jezik, najčešće u svrhu manipuliranja memorije i optimiziranje performansi.

Nizovi nizova i metoda intern ()

Za spremanje a Stringu Stringbazen koristimo tehniku ​​koja se naziva Stringinterniranje . Evo što nam Javadoc govori o intern()metodi:

 /** * Returns a canonical representation for the string object. * * A pool of strings, initially empty, is maintained privately by the * class {@code String}. * * When the intern method is invoked, if the pool already contains a * string equal to this {@code String} object as determined by * the {@link #equals(Object)} method, then the string from the pool is * returned. Otherwise, this {@code String} object is added to the * pool and a reference to this {@code String} object is returned. * * It follows that for any two strings {@code s} and {@code t}, * {@code s.intern() == t.intern()} is {@code true} * if and only if {@code s.equals(t)} is {@code true}. * * All literal strings and string-valued constant expressions are * interned. String literals are defined in section 3.10.5 of the * The Java™ Language Specification. * * @returns a string that has the same contents as this string, but is * guaranteed to be from a pool of unique strings. * @jls 3.10.5 String Literals */ public native String intern(); 

intern()Metoda se koristi za pohranu Strings u Stringbazenu. Prvo provjerava postoji Stringli već stvoreno u spremištu. Ako nije, stvara se novo Stringu bazenu. Iza kulisa, logika Stringudruživanja temelji se na uzorku muha.

Sad, primijetite što se događa kada newključnu riječ prisilimo na stvaranje dvaju Strings:

 String duke = new String("duke"); String duke2 = new String("duke"); System.out.println(duke == duke2); // The result will be false here System.out.println(duke.intern() == duke2.intern()); // The result will be true here 

Za razliku od prethodnog primjera s newključnom riječi, u ovom se slučaju usporedba pokazuje istinitom. To je zato što upotreba intern()metode osigurava Stringpohranu s u spremište.

Jednaka metoda s klasom String

equals()Metoda se koristi kako bi provjerili da je država od dva Java klase su isti. Budući da equals()je iz Objectklase, svaka je klasa Java nasljeđuje. No, equals()metodu treba nadjačati kako bi ona ispravno funkcionirala. Naravno, Stringponištava equals().

Pogledaj:

 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(value, aString.value) : StringUTF16.equals(value, aString.value); } } return false; } 

Kao što vidite, stanje Stringvrijednosti klase mora biti, equals()a ne referenca na objekt. Nije važno je li referenca na objekt drugačija; Stringuspoređuje se stanje volje.

Najčešće metode niza

Postoji samo jedna zadnja stvar koju trebate znati prije nego što se odlučite za Stringusporedbu. Razmotrite ove uobičajene metode Stringklase:

 // Removes spaces from the borders trim() // Gets a substring by indexes substring(int beginIndex, int endIndex) // Returns the characters length of the String length() // Replaces String, regex can be used. replaceAll(String regex, String replacement) // Verifies if there is a specified CharSequence in the String contains(CharSequences) 

Prihvatite izazov usporedbe žica!

Isprobajmo što ste naučili o Stringpredavanju u brzom izazovu.

Za ovaj izazov usporedit ćete nekoliko Strings pomoću koncepata koje smo istražili. Gledajući donji kod, možete li odrediti konačnu vrijednost svake varijable rezultata ?

 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(result); } } 

Koji izlaz predstavlja konačnu vrijednost varijable rezultata?

O : 02468

B : 12469

C : 12579

D : 12568

Odgovor provjerite ovdje.

Što se upravo dogodilo? Razumijevanje ponašanja niza

U prvom retku koda vidimo:

 result += " powerfulCode ".trim() == "powerfulCode" ? "0" : "1"; 

Iako Stringće biti isto nakon trim()pozivanja metode, String“ powerfulcode “u početku je bilo drugačije. U ovom je slučaju usporedba takva false, jer kada trim()metoda uklanja razmake od granica, ona prisiljava stvaranje novog Strings novim operatorom.

Dalje vidimo:

 result += "flexibleCode" == "flexibleCode" ? "2" : "3"; 

No mystery here, the Strings are the same in the String pool. This comparison returns true.

Next, we have:

 result += new String("doYourBest") == new String("doYourBest") ? "4" : "5"; 

Using the new reserved keyword forces the creation of two new Strings, whether they are equal or not. In this case the comparison will be false even if the String values are the same.

Next is:

 result += new String("noBugsProject") .equals("noBugsProject") ? "6" : "7"; 

Because we’ve used the equals() method, the value of the String will be compared and not the object instance. In that case, it doesn’t matter if the objects are different because the value is being compared. This comparison returns true.

Finally, we have:

 result += new String("breakYourLimits").intern() == new String("breakYourLimits").intern() ? "8" : "9"; 

As you’ve seen before, the intern() method puts the String in the String pool. Both Strings point to the same object, so in this case the comparison is true.

Video challenge! Debugging String comparisons

Debugging is one of the easiest ways to fully absorb programming concepts while also improving your code. In this video you can follow along while I debug and explain the Java Strings challenge:

Common mistakes with Strings

It can be difficult to know if two Strings are pointing to the same object, especially when the Strings contain the same value. It helps to remember that using the reserved keyword new always results in a new object being created in memory, even if the values are the same.

Using String methods to compare Object references can also be tricky. The key is, if the method changes something in the String, the object references will be different.

A few examples to help clarify:

 System.out.println("duke".trim() == "duke".trim());; 

This comparison will be true because the trim() method does not generate a new String.

 System.out.println(" duke".trim() == "duke".trim()); 

In this case, the first trim() method will generate a new String because the method will execute its action, so the references will be different.

Finally, when trim() executes its action, it creates a new String:

 // Implementation of the trim method in the String class new String(Arrays.copyOfRange(val, index, index + len), LATIN1); 

What to remember about Strings

  • Strings are immutable, so a String’s state can’t be changed.
  • To conserve memory, the JVM keeps Strings in a String pool. When a new String is created, the JVM checks its value and points it to an existing object. If there is no String with that value in the pool, then the JVM creates a new String.
  • Korištenje ==operatora uspoređuje referencu objekta. Korištenjem equals()metode uspoređuje se vrijednost String. Isto pravilo primijenit će se na sve objekte.
  • Kada se koristi newoperator, Stringu Stringspremištu će se stvoriti novi, čak i ako postoji a Strings istom vrijednošću.

 

Kljucni odgovor

Odgovor na ovaj Java izazivač je opcija D. Rezultat bi bio 12568.

Ovu priču, "Usporedbe nizova u Javi" izvorno je objavio JavaWorld.