Perbandingan rentetan di Jawa

Di Java, Stringkelas merangkumi pelbagai char. Sederhananya, Stringadalah pelbagai watak yang digunakan untuk menyusun kata, ayat, atau data lain yang anda mahukan.

Encapsulation adalah salah satu konsep yang paling kuat dalam pengaturcaraan berorientasikan objek. Kerana enkapsulasi, anda tidak perlu tahu bagaimana kelas String berfungsi; anda hanya perlu mengetahui kaedah apa yang harus digunakan pada antara muka.

Apabila anda melihat Stringkelas di Java, anda dapat melihat bagaimana susunan array chardikemas:

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

Untuk memahami enkapsulasi dengan lebih baik, pertimbangkan objek fizikal: kereta. Adakah anda perlu tahu bagaimana kereta berfungsi di bawah tudung untuk memandu? Sudah tentu tidak, tetapi anda mesti tahu apa yang dilakukan antara muka kereta: perkara seperti pemecut, brek, dan stereng. Setiap antara muka ini menyokong tindakan tertentu: mempercepat, brek, belok kiri, belok kanan. Ia sama dalam pengaturcaraan berorientasikan objek.

Blog pertama saya dalam siri Java Challengers memperkenalkan kaedah overloading, yang merupakan teknik yang digunakan oleh Stringkelas secara meluas. Beban berlebihan dapat menjadikan kelas anda benar-benar fleksibel, termasuk 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…... 

Daripada cuba memahami bagaimana Stringkelas berfungsi, Java Challenger ini akan membantu anda memahami apa yang dilakukannya dan bagaimana menggunakannya dalam kod anda.

Apa itu kolam String?

Stringmungkin kelas yang paling banyak digunakan di Jawa. Sekiranya objek baru dibuat di timbunan memori setiap kali kita menggunakan String, kita akan membuang banyak memori. Kumpulan Stringmenyelesaikan masalah ini dengan menyimpan hanya satu objek untuk setiap Stringnilai, seperti yang ditunjukkan di bawah.

Rafael Chinelato Del Nero

Walaupun kami membuat Stringpemboleh ubah untuk Dukedan JuggyString, hanya dua objek yang dibuat dan disimpan di timbunan memori. Untuk bukti, lihat contoh kod berikut. (Ingat bahawa ==operator " " di Java digunakan untuk membandingkan dua objek dan menentukan sama ada objek itu sama.)

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

Kod ini akan kembali truekerana kedua-duanya Stringmenunjuk ke objek yang sama di Stringkolam. Nilai mereka sama.

Pengecualian: Pengendali 'baru'

Sekarang lihat kod ini - ia kelihatan serupa dengan sampel sebelumnya, tetapi ada perbezaannya.

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

Berdasarkan contoh sebelumnya, anda mungkin menganggap kod ini akan kembali true, tetapi sebenarnya false. Menambah newoperator memaksa penciptaan baru Stringdi timbunan memori. Oleh itu, JVM akan membuat dua objek yang berbeza.

Kaedah asli

A Cara speakers di Jawa adalah satu kaedah yang akan disusun menggunakan bahasa C, biasanya untuk tujuan memanipulasi memori dan mengoptimumkan prestasi.

String pool dan kaedah intern ()

Untuk menyimpan Stringdi Stringkolam renang, kami menggunakan teknik yang disebut Stringinterning . Inilah yang diberitahu oleh Javadoc mengenai intern()kaedahnya:

 /** * 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(); 

The intern()kaedah yang digunakan ke kedai Stringdi sebuah Stringkolam. Pertama, ia mengesahkan jika yang Stringanda buat sudah ada di kolam. Sekiranya tidak, ia akan menghasilkan yang baru Stringdi kolam renang. Di sebalik tabir, logik kumpulan Stringberdasarkan corak Flyweight.

Sekarang, perhatikan apa yang berlaku apabila kita menggunakan newkata kunci untuk memaksa penciptaan dua 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 

Tidak seperti contoh sebelumnya dengan newkata kunci, dalam kes ini perbandingan ternyata benar. Ini kerana menggunakan intern()kaedah memastikan Strings akan disimpan di kolam.

Kaedah yang sama dengan kelas String

The equals()kaedah yang digunakan untuk mengesahkan sama keadaan dua kelas Java adalah sama. Kerana equals()dari Objectkelas, setiap kelas Java mewarisinya. Tetapi equals()kaedah itu harus ditolak untuk menjadikannya berfungsi dengan baik. Sudah tentu, Stringmengatasi equals().

Tengoklah:

 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; } 

Seperti yang anda lihat, keadaan nilai Stringkelas mestilah equals()dan bukan rujukan objek. Tidak menjadi masalah jika rujukan objek berbeza; keadaan Stringkehendak akan dibandingkan.

Kaedah rentetan yang paling biasa

Hanya ada satu perkara terakhir yang perlu anda ketahui sebelum Stringmenempuh cabaran perbandingan. Pertimbangkan kaedah umum Stringkelas ini:

 // 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) 

Ikuti cabaran perbandingan String!

Mari cuba apa yang anda pelajari mengenai Stringkelas dalam cabaran pantas.

Untuk cabaran ini, anda akan membandingkan sejumlah Stringmenggunakan konsep yang telah kami terokai. Melihat kod di bawah, bolehkah anda menentukan nilai akhir setiap pemboleh ubah hasil ?

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

Output yang manakah mewakili nilai akhir pemboleh ubah hasil?

J : 02468

B : 12469

C : 12579

D : 12568

Lihat jawapan anda di sini.

Apa yang baru berlaku? Memahami tingkah laku String

Pada baris pertama kod, kita melihat:

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

Walaupun Stringwasiat akan sama setelah trim()metode ini digunakan, String“ powerfulcode “itu berbeza pada awalnya. Dalam kes ini, perbandingannya adalah false, kerana apabila trim()kaedah menghilangkan ruang dari sempadan, ia memaksa penciptaan baru Stringdengan operator baru.

Seterusnya, kita melihat:

 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.
  • Menggunakan ==operator membandingkan rujukan objek. Menggunakan equals()kaedah membandingkan nilai String. Peraturan yang sama akan diterapkan pada semua objek.
  • Semasa menggunakan newpengendali, yang baru Stringakan dibuat di Stringkolam walaupun ada Stringdengan nilai yang sama.

 

Kunci jawapan

Jawapan untuk pencabar Java ini adalah Pilihan D. Hasilnya adalah 12568.

Kisah ini, "String perbandingan di Java" awalnya diterbitkan oleh JavaWorld.