Mengapa CharSequence tidak mendefinisikan berisi (CharSequence)?

11

Ini berlaku untuk Java SE & Android, karena kontraknya identik.

CharSequencetidak mendefinisikan suatu contains(CharSequence)metode. Saya tidak dapat menemukan alasan mengapa, dan memasukkannya akan sangat berguna, mencegah perlunya menelepon CharSequence#toString()untuk memeriksa urutan karakter.

Sebagai contoh, di Android, pengguna dipaksa menelepon Editable#toString()untuk melihat apakah itu berisi urutan karakter, meskipun Editablemengimplementasikan CharSequence, yang dapat dihindari jika CharSequencedidefinisikan contains(CharSequence).

Apa ide di balik pilihan desain ini? Apakah ini potensi pengawasan, atau adakah alasan desain untuk ini?

Vince Emigh
sumber

Jawaban:

10

Intinya CharSequenceadalah untuk memberikan tampilan hanya baca ke urutan karakter, dan hanya itu. Antarmuka ini tidak menyediakan manipulasi string atau metode pencarian. Itu di luar jangkauan.

Prinsip Segregasi Antarmuka menyarankan bahwa klien dari suatu tipe tidak boleh bergantung pada metode yang tidak mereka gunakan. Oleh karena itu, sebuah antarmuka harus menyatakan hanya set minimal yang bermanfaat. Jika use case yang berbeda membutuhkan metode yang berbeda, harus ada antarmuka yang berbeda.

Klien yang hanya membutuhkan sumber karakter kemungkinan tidak membutuhkan metode pencarian.

Tentu saja mungkin untuk berlebihan Prinsip ini dan berakhir dengan seribu antarmuka kecil. Itu juga tidak baik. Jadi CharSequenceantarmuka tidak hanya berisi metode minimal charAt()dan length(), tetapi juga metode kenyamanan yang sangat terkait subSequence(). (A CharSequence kemungkinan dapat memberikan tampilan ke urutan tanpa salinan string, itulah sebabnya ini harus menjadi metode instance). Menentukan toString()tidak apa-apa karena metode itu akan tetap diwarisi dari Object. Metode chars()dan codePoints()beradaptasi CharSequencedengan Streamantarmuka. Karena ini adalah metode default, mereka tidak memaksakan persyaratan tambahan untuk implementasi kelas CharSequence.

The CharSequencejenis ini berguna bila metode membutuhkan sumber karakter generik tanpa menentukan implementasi tertentu (misalnya String vs CharBuffer vs StringBuilder). Metode String#join()dan String#contains()adalah contoh yang baik dari menggunakan CharSequences.

Tidak perlu untuk CharSequencememberikan contains()metode karena dapat diterapkan secara eksternal. Meskipun Java tidak memiliki kenyamanan metode ekstensi C #, metode statis pada dasarnya adalah hal yang sama. Jadi, alih-alih boolean Editable#contains(CharSequence needle)Anda akan memiliki static boolean contains(CharSequence haystack, CharSequence needle). Algoritma pencarian string adalah topik ilmu komputer yang dipelajari dengan baik. Algoritma yang berbeda dengan pengorbanan yang berbeda sudah tersedia.

Bacaan lebih lanjut:

amon
sumber
2
Anda menyebutkan " antarmuka ini tidak menyediakan string manipulasi atau metode pencarian. Mereka berada di luar ruang lingkup. ", Tapi containsbukan metode mutasi, dan ada tidak metode yang ada pencarian ( charAt), jadi bagaimana ini berlaku ?. Juga, " Karena ini adalah metode default, mereka tidak memaksakan persyaratan tambahan untuk kelas yang mengimplementasikan CharSequence. " - Tidak containsdapat diimplementasikan sebagai default melalui impl return to String().contains(...), menghapus persyaratan untuk mengimplementasikan kelas?
Vince Emigh
1
@VinceEmigh Ya, contains()bisa menjadi metode default. Jika ada itu tidak harus diimplementasikan dalam hal String#containstetapi sebaliknya: String harus menggunakan implementasi CharSequence. The charAt()berbeda. Itu tidak menerapkan algoritma pencarian, itu adalah bagian penting dari CharSequence: tanpa itu, isinya tidak dapat disalin ke jenis yang berbeda seperti String. Streaming adalah bagian penting dari Java8, dan menambahkan metode default ini sejalan dengan penambahan ke antarmuka lain seperti Collection.
amon