Perbandingan string di Java

Di Java, Stringkelas merangkum larik char. Sederhananya, Stringadalah larik karakter yang digunakan untuk menulis kata, kalimat, atau data lain yang Anda inginkan.

Enkapsulasi adalah salah satu konsep paling kuat dalam pemrograman berorientasi objek. Karena enkapsulasi, Anda tidak perlu mengetahui cara kerja kelas String; Anda hanya perlu mengetahui metode apa yang digunakan pada antarmukanya.

Saat Anda melihat Stringkelas di Java, Anda dapat melihat bagaimana array chardienkapsulasi:

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

Untuk memahami enkapsulasi dengan lebih baik, pertimbangkan objek fisik: mobil. Apakah Anda perlu mengetahui cara kerja mobil di bawah kap untuk mengendarainya? Tentu tidak, tetapi Anda perlu tahu apa yang dilakukan antarmuka mobil: hal-hal seperti akselerator, rem, dan setir. Masing-masing antarmuka ini mendukung tindakan tertentu: akselerasi, rem, belok kiri, belok kanan. Itu sama dalam pemrograman berorientasi objek.

Blog pertama saya dalam seri Java Challengers memperkenalkan metode overloading, yang merupakan teknik yang Stringdigunakan kelas secara ekstensif. Kelebihan beban dapat membuat kelas Anda sangat 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 mencoba memahami cara kerja Stringkelas, Java Challenger ini akan membantu Anda memahami apa yang dilakukannya dan cara menggunakannya dalam kode Anda.

Apa itu String pool?

Stringmungkin merupakan kelas yang paling sering digunakan di Java. Jika objek baru dibuat di heap memori setiap kali kami menggunakan String, kami akan membuang banyak memori. The Stringpool memecahkan masalah ini dengan menyimpan hanya satu objek untuk setiap Stringnilai, seperti yang ditunjukkan di bawah ini.

Rafael Chinelato Del Nero

Meskipun kita membuat Stringvariabel untuk Dukedan JuggyStrings, hanya dua objek yang dibuat dan disimpan di heap memori. Sebagai bukti, lihat contoh kode berikut. (Ingatlah bahwa ==operator " " di Java digunakan untuk membandingkan dua objek dan menentukan apakah keduanya sama.)

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

Kode ini akan kembali truekarena keduanya Stringmenunjuk ke objek yang sama di Stringkolam. Nilainya sama.

Pengecualian: Operator 'baru'

Sekarang lihat kode ini - terlihat mirip dengan contoh sebelumnya, tetapi ada perbedaan.

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

Berdasarkan contoh sebelumnya, Anda mungkin mengira kode ini akan kembali true, tetapi sebenarnya false. Menambahkan newoperator memaksa pembuatan yang baru Stringdi heap memori. Jadi, JVM akan membuat dua objek berbeda.

Metode asli

Sebuah metode asli di Jawa adalah metode yang akan dikompilasi dengan menggunakan bahasa C, biasanya untuk tujuan memanipulasi memori dan mengoptimalkan kinerja.

Kumpulan string dan metode intern ()

Untuk menyimpan Stringdi dalam Stringpool, kami menggunakan teknik yang disebut Stringinterning . Inilah yang Javadoc beri tahu tentang intern()metode ini:

 /** * 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()metode yang digunakan untuk menyimpan Stringdalam sebuah Stringkolam renang. Pertama, ini memverifikasi jika yang StringAnda buat sudah ada di kolam. Jika tidak, itu membuat yang baru Stringdi kolam. Di balik layar, logika Stringpenyatuan didasarkan pada pola Kelas Terbang.

Sekarang, perhatikan apa yang terjadi ketika kita menggunakan newkata kunci untuk memaksa pembuatan 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 

Berbeda dengan contoh sebelumnya dengan newkata kunci, dalam hal ini ternyata perbandingannya benar. Itu karena menggunakan intern()metode ini memastikan Strings akan disimpan di kolam.

Metode yang sama dengan kelas String

The equals()metode yang digunakan untuk memverifikasi apakah keadaan dua kelas Java adalah sama. Karena equals()dari Objectkelas, setiap kelas Java mewarisinya. Tetapi equals()metode ini harus diganti agar dapat berfungsi dengan baik. Tentu saja, Stringmenimpa equals().

Lihatlah:

 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, status nilai Stringkelas haruslah equals()dan bukan referensi objek. Tidak masalah jika referensi objek berbeda; keadaan Stringakan dibandingkan.

Metode String yang paling umum

Hanya ada satu hal terakhir yang perlu Anda ketahui sebelum mengambil Stringtantangan perbandingan. Pertimbangkan metode 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) 

Ambil tantangan perbandingan String!

Mari kita coba apa yang telah Anda pelajari tentang Stringkelas dalam tantangan singkat.

Untuk tantangan ini, Anda akan membandingkan beberapa Stringmenggunakan konsep yang telah kita jelajahi. Melihat kode di bawah ini, dapatkah Anda menentukan nilai akhir dari setiap variabel 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 mana yang mewakili nilai akhir dari variabel hasil?

J : 02468

B : 12469

C : 12579

D : 12568

Cek jawaban Anda di sini.

Apa yang baru saja terjadi? Memahami perilaku String

Di baris pertama kode, kita melihat:

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

Meskipun Stringakan sama setelah trim()metode tersebut dipanggil, pada String“ powerfulcode “awalnya berbeda. Dalam hal ini perbandingannya adalah false, karena ketika trim()metode menghilangkan spasi dari perbatasan itu memaksa pembuatan baru Stringdengan operator baru.

Selanjutnya, kita lihat:

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

Tidak ada misteri di sini, Stringsama saja di Stringkolam renang. Perbandingan ini kembali true.

Selanjutnya, kami memiliki:

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

Menggunakan newkata kunci yang dicadangkan memaksa pembuatan dua Strings baru , apakah keduanya sama atau tidak. Dalam hal ini, perbandingannya akan tetap falsesama jika Stringnilainya sama.

Berikutnya adalah:

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

Karena kita telah menggunakan equals()metode ini, nilai dari Stringakan dibandingkan dan bukan contoh objeknya. Dalam hal ini, tidak masalah jika objeknya berbeda karena nilainya akan dibandingkan. Perbandingan ini kembali true.

Akhirnya, kami memiliki:

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

Seperti yang Anda lihat sebelumnya, intern()metode ini menempatkan Stringdi dalam Stringkumpulan. Keduanya Stringmenunjuk ke objek yang sama, jadi dalam hal ini adalah perbandingannya 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 referensi objek. Menggunakan equals()metode tersebut membandingkan nilai dari String. Aturan yang sama akan diterapkan ke semua objek.
  • Saat menggunakan newoperator, yang baru Stringakan dibuat di Stringkumpulan meskipun ada Stringdengan nilai yang sama.

 

Kunci jawaban

Jawaban untuk penantang Java ini adalah Opsi D. Outputnya adalah 12568.

Artikel ini, "Perbandingan string di Java", awalnya diterbitkan oleh JavaWorld.