Pemrograman dalam Android, sebagian besar nilai teks diharapkan masuk CharSequence
.
Mengapa demikian? Apa manfaatnya, dan apa dampak utama dari penggunaan CharSequence
berlebihan String
?
Apa perbedaan utama, dan masalah apa yang diharapkan, saat menggunakannya, dan mengubah satu sama lain?
java
string
charsequence
e-satis
sumber
sumber
Jawaban:
String adalah CharSequences , jadi Anda bisa menggunakan String dan tidak khawatir. Android hanya berusaha membantu dengan memungkinkan Anda juga menentukan objek CharSequence lainnya, seperti StringBuffers.
sumber
CharSequence
javadoc: Antarmuka ini tidak memperbaiki kontrak umumequals
danhashCode
metode.CharSequence
Oleh karena itu, hasil membandingkan dua objek yang mengimplementasikan secara umum tidak terdefinisi . Setiap objek dapat diimplementasikan oleh kelas yang berbeda, dan tidak ada jaminan bahwa masing-masing kelas akan dapat menguji instansnya untuk persamaan dengan yang lainnya. Oleh karena itu tidak tepat untuk menggunakanCharSequence
instance sembarang sebagai elemen dalam set atau sebagai kunci dalam peta.CharSequence
adalah retrofit di JDK 1.4 untuk memperkenalkan antarmuka umum tujuan terbatas ke objek yang berisi urutan karakter. Beberapa objek tersebut berisi keadaan lain, jadi mungkin tidak masuk akal untuk mendefinisikanObject.equals
sebagai "berisi urutan karakter yang sama". NIOCharBuffer
, misalnya, hanya mengekspos karakter antaraposition
danlimit
sebagaiCharSequence
, meskipun berpotensi menahan banyak karakter lain.equals
/hashCode
aktifObject
di tempat pertama ....Object
atauCharSequence
, tidak ada antarmuka yang diperlukan untuk memberikan kewarasan kesetaraan antara implementasi. Tidak ada duaCollection
s yang diperlukan untuk memberikan persamaan antarCollection
antarmuka, tetapi mereka bisa jika mereka mau. IMHOCharSequence
harus dibatasi pada input dan digunakan lebih sedikit untuk jenis pengembalian.CharSequence
= antarmukaString
= implementasi konkretCharSequence
adalah sebuah antarmuka .String
adalah salah satu kelas tersebut, implementasi konkret dariCharSequence
.Kamu berkata:
Tidak ada konversi dari
String
.String
objek adalah aCharSequence
.CharSequence
dapat menghasilkan aString
. PanggilCharSequence::toString
. JikaCharSequence
kebetulan menjadiString
, maka metode mengembalikan referensi ke objeknya sendiri.Dengan kata lain, setiap
String
adalah aCharSequence
, tetapi tidak setiapCharSequence
adalah aString
.Pemrograman ke antarmuka
Secara umum, pemrograman ke antarmuka lebih baik daripada pemrograman ke kelas konkret. Ini menghasilkan fleksibilitas, sehingga kami dapat beralih di antara implementasi konkret antarmuka tertentu tanpa melanggar kode lainnya.
Saat mengembangkan API untuk digunakan oleh berbagai programer dalam berbagai situasi, tulis kode Anda untuk memberi dan mengambil antarmuka yang paling umum. Ini memberi programmer panggilan kebebasan untuk menggunakan berbagai implementasi dari antarmuka itu, implementasi mana yang terbaik untuk konteks khusus mereka.
Misalnya, lihat Java Collections Framework . Jika API Anda memberi atau mengambil koleksi memerintahkan objek, menyatakan metode Anda sebagai menggunakan
List
bukanArrayList
,LinkedList
, atau implementasi pihak ke-3 lainnyaList
.Saat menulis metode kecil cepat-dan-kotor untuk hanya digunakan oleh kode Anda di satu tempat tertentu, bukan menulis API yang akan digunakan di banyak tempat, Anda tidak perlu repot-repot menggunakan antarmuka yang lebih umum daripada beton khusus kelas. Tetapi meskipun begitu, tidak ada salahnya menggunakan antarmuka paling umum yang Anda bisa.
String
Anda tahu Anda memiliki satu bagian teks, seluruhnya dalam memori, dan tidak berubah.CharSequence
, Anda tidak tahu apa fitur khusus dari implementasi konkret mungkin.The
CharSequence
objek mungkin mewakili potongan besar teks, dan karena itu memiliki implikasi memori. Atau mungkin banyak potongan teks yang dilacak secara terpisah yang perlu dijahit bersama saat Anda menelepontoString
, dan karenanya memiliki masalah kinerja. Implementasinya bahkan dapat mengambil teks dari layanan jarak jauh, dan karenanya memiliki implikasi latensi.Anda biasanya tidak akan mengkonversi bolak-balik. A
String
adalah aCharSequence
. Jika metode Anda menyatakan bahwa dibutuhkanCharSequence
, pemrogram pemanggil dapat melewatkanString
objek, atau mungkin melewatkan sesuatu yang lain seperti aStringBuffer
atauStringBuilder
. Kode metode Anda hanya akan menggunakan apa pun yang diteruskan, memanggil salah satuCharSequence
metode.Yang paling dekat dengan konversi Anda adalah jika kode Anda menerima
CharSequence
dan Anda tahu Anda perluString
. Mungkin Anda berinteraksi dengan kode lama yang ditulis keString
kelas daripada ditulis keCharSequence
antarmuka. Atau mungkin kode Anda akan bekerja secara intensif dengan teks, seperti mengulang berulang kali atau menganalisis. Dalam hal ini, Anda hanya ingin mengambil satu kemungkinan performa yang dicapai hanya sekali, jadi Anda menelepon terlebih dahulutoString
. Kemudian lanjutkan dengan pekerjaan Anda menggunakan apa yang Anda tahu sebagai satu bagian teks yang seluruhnya ada dalam memori.Sejarah bengkok
Perhatikan komentar yang dibuat pada Jawaban yang diterima . The
CharSequence
antarmuka itu dipasang ke struktur kelas yang ada, jadi ada beberapa kehalusan penting (equals()
&hashCode()
). Perhatikan berbagai versi Java (1, 2, 4 & 5) yang ditandai pada kelas / antarmuka — cukup banyak churn selama bertahun-tahun. IdealnyaCharSequence
sudah ada sejak awal, tetapi itulah kehidupan.Diagram kelas saya di bawah ini dapat membantu Anda melihat gambaran besar tipe string di Java 7/8. Saya tidak yakin apakah semua ini ada di Android, tetapi konteks keseluruhan masih terbukti bermanfaat bagi Anda.
sumber
Saya percaya yang terbaik adalah menggunakan CharSequence. Alasannya adalah bahwa String mengimplementasikan CharSequence, oleh karena itu Anda dapat meneruskan sebuah String ke dalam CharSequence, NAMUN Anda tidak dapat meneruskan sebuah CharSequence ke dalam sebuah String, karena CharSequence tidak mengimplementasikan String. JUGA, di Android
EditText.getText()
metode mengembalikan Editable, yang juga mengimplementasikan CharSequence dan dapat dilewatkan dengan mudah menjadi satu, sementara tidak mudah menjadi String. CharSequence menangani semuanya!sumber
charSequence.toString()
Secara umum menggunakan antarmuka memungkinkan Anda untuk memvariasikan implementasi dengan kerusakan jaminan minimal. Meskipun java.lang.String sangat populer mungkin dalam konteks tertentu seseorang mungkin ingin menggunakan implementasi lain. Dengan membangun API di sekitar CharSequences daripada Strings, kode memberi seseorang peluang untuk melakukan itu.
sumber
Ini hampir pasti alasan kinerja. Misalnya, bayangkan parser yang melewati string 500k ByteBuffer yang berisi.
Ada 3 pendekatan untuk mengembalikan konten string:
Bangun String [] pada waktu parse, satu karakter pada satu waktu. Ini akan memakan banyak waktu. Kita bisa menggunakan == daripada .equals untuk membandingkan referensi yang di-cache.
Bangun int [] dengan offset pada waktu parse, lalu bangun String secara dinamis saat get () terjadi. Setiap String akan menjadi objek baru, jadi tidak ada caching yang mengembalikan nilai dan menggunakan ==
Bangun CharSequence [] pada saat parse. Karena tidak ada data baru disimpan (selain offset ke buffer byte), penguraian jauh lebih rendah daripada # 1. Saat mendapatkan, kita tidak perlu membuat String, jadi mendapatkan kinerja sama dengan # 1 (jauh lebih baik dari # 2), karena kami hanya mengembalikan referensi ke objek yang ada.
Selain keuntungan pemrosesan yang Anda dapatkan menggunakan CharSequence, Anda juga mengurangi jejak memori dengan tidak menggandakan data. Misalnya, jika Anda memiliki buffer yang berisi 3 paragraf teks, dan ingin mengembalikan semua 3 atau satu paragraf, Anda perlu 4 Strings untuk mewakili ini. Menggunakan CharSequence Anda hanya perlu 1 buffer dengan data, dan 4 contoh implementasi CharSequence yang melacak awal dan panjang.
sumber
CharSequence
implementasi Anda sendiri untuk itu.CharSequence
adalah antarmuka - menurut definisi, ia tidak memiliki detail implementasi yang Anda diskusikan karena ia tidak memiliki implementasi sendiri. AString
adalah salah satu dari beberapa kelas konkret yang mengimplementasikanCharSequence
antarmuka. Jadi aString
adalah aCharSequence
. Anda dapat membandingkan detail kinerjaString
vsStringBuffer
vsStringBuilder
, tetapi tidakCharSequence
. Menulis "memproses keuntungan yang Anda dapatkan menggunakan CharSequence" tidak ada artinya.Masalah yang muncul dalam kode Android praktis adalah membandingkannya dengan CharSequence.equals valid tetapi tidak selalu berfungsi sebagaimana dimaksud.
Perbandingan harus dilakukan oleh
sumber
Konsekuensi
A
CharSequence
adalah antarmuka, bukan kelas yang sebenarnya. Antarmuka hanyalah seperangkat aturan (metode) yang harus dimiliki kelas jika mengimplementasikan antarmuka. Di Android aCharSequence
adalah payung untuk berbagai jenis string teks. Berikut adalah beberapa yang umum:String
(teks tidak berubah tanpa rentang gaya)StringBuilder
(teks bisa berubah tanpa rentang styling)SpannableString
(teks abadi dengan rentang gaya)SpannableStringBuilder
(teks bisa berubah dengan rentang styling)(Anda dapat membaca lebih lanjut tentang perbedaan antara ini di sini .)
Jika Anda memiliki
CharSequence
objek, maka sebenarnya objek dari salah satu kelas yang diimplementasikanCharSequence
. Sebagai contoh:Manfaat memiliki jenis payung umum seperti
CharSequence
adalah Anda dapat menangani banyak jenis dengan satu metode. Sebagai contoh, jika saya memiliki metode yang menggunakanCharSequence
parameter, saya bisa memasukkan aString
atau aSpannableStringBuilder
dan itu akan menangani salah satunya.Tali
Anda dapat mengatakan bahwa
String
hanya satu jenisCharSequence
. Namun, tidak sepertiCharSequence
, ini adalah kelas yang sebenarnya, sehingga Anda dapat membuat objek dari itu. Jadi Anda bisa melakukan ini:tetapi Anda tidak bisa melakukan ini:
Karena
CharSequence
hanya daftar aturan yangString
sesuai, Anda dapat melakukan ini:Itu berarti bahwa setiap kali suatu metode meminta
CharSequence
, tidak masalah untuk memberikannyaString
.Namun, yang terjadi adalah sebaliknya. Jika metode ini mengambil
String
parameter, Anda tidak bisa meneruskannya sesuatu yang hanya dikenal sebagai aCharSequence
, karena mungkin sebenarnya berupaSpannableString
atau sejenisnyaCharSequence
.sumber
CharSequence
adalah antarmuka danString
mengimplementasikannya. Anda dapat membuat instantiateString
tetapi Anda tidak bisa melakukannyaCharSequence
karena itu adalah antarmuka. Anda dapat menemukan implementasi lain diCharSequence
dalam situs web resmi Java.sumber
CharSequence adalah urutan nilai char yang dapat dibaca yang mengimplementasikan String. ini memiliki 4 metode
Silakan lihat dokumentasi dokumentasi CharSequence
sumber
CharSequence
tidak menerapkanString
. Kebalikannya benar.