Mereka pada dasarnya adalah kuda untuk kursus.
Scanner
dirancang untuk kasus di mana Anda perlu mengurai string, mengeluarkan data dari berbagai jenis. Ini sangat fleksibel, tetapi bisa dibilang tidak memberi Anda API paling sederhana untuk sekadar mendapatkan serangkaian string yang dibatasi oleh ekspresi tertentu.
String.split()
dan Pattern.split()
memberi Anda sintaks mudah untuk melakukan yang terakhir, tetapi pada dasarnya itulah yang mereka lakukan. Jika Anda ingin mengurai string yang dihasilkan, atau mengubah pembatas setengah jalan tergantung pada token tertentu, mereka tidak akan membantu Anda dengan itu.
StringTokenizer
bahkan lebih membatasi daripada String.split()
, dan juga sedikit lebih fiddlier untuk digunakan. Ini pada dasarnya dirancang untuk menarik token yang dibatasi oleh substring tetap. Karena pembatasan ini, sekitar dua kali lebih cepat String.split()
. (Lihat perbandinganString.split()
StringTokenizer
saya tentang dan .) Itu juga ada sebelum API ekspresi reguler, yang String.split()
merupakan bagiannya.
Anda akan mencatat dari timing saya yang String.split()
masih dapat menandai ribuan string dalam beberapa milidetik pada mesin biasa. Selain itu, ia memiliki keunggulan dibandingkan StringTokenizer
memberi Anda output sebagai array string, yang biasanya Anda inginkan. Menggunakan Enumeration
, seperti yang disediakan oleh StringTokenizer
, terlalu "rewel secara sintaksis" sebagian besar waktu. Dari sudut pandang ini, StringTokenizer
sedikit membuang-buang ruang saat ini, dan Anda mungkin juga hanya menggunakan String.split()
.
StringTokenizer
masih taruhan terbaik saya karenaString.split()
hanya akan kehabisan memori?Mari kita mulai dengan menghilangkan
StringTokenizer
. Semakin tua dan bahkan tidak mendukung ekspresi reguler. Dokumentasinya menyatakan:Jadi mari kita membuangnya segera. Itu pergi
split()
danScanner
. Apa perbedaan di antara mereka?Untuk satu hal,
split()
cukup kembalikan array, yang membuatnya mudah untuk menggunakan foreach loop:Scanner
dibangun lebih seperti aliran:atau
(Ini memiliki API yang agak besar , jadi jangan berpikir bahwa itu selalu terbatas pada hal-hal sederhana seperti itu.)
Antarmuka gaya aliran ini dapat berguna untuk mem-parsing file teks sederhana atau input konsol, ketika Anda tidak memiliki (atau tidak bisa mendapatkan) semua input sebelum mulai mengurai.
Secara pribadi, satu-satunya waktu saya bisa ingat menggunakan
Scanner
adalah untuk proyek sekolah, ketika saya harus mendapatkan input pengguna dari baris perintah. Itu membuat operasi semacam itu mudah. Tetapi jika saya memiliki sesuatuString
yang ingin saya pisahkan, hampir tidak ada alasan untuk pergisplit()
.sumber
Scanner
untuk mendeteksi karakter baris baru dalam suatu pemberianString
. Karena karakter baris baru dapat bervariasi dari platform ke platform (lihat diPattern
javadoc!) Dan string input TIDAK dijamin sesuaiSystem.lineSeparator()
, saya merasaScanner
lebih cocok karena sudah tahu karakter baris baru apa yang harus dicari ketika meneleponnextLine()
. KarenaString.split
saya harus memberi makan dalam pola regex yang benar untuk mendeteksi pemisah baris, yang saya temukan tidak disimpan di lokasi standar (yang terbaik yang bisa saya lakukan adalah menyalinnya dari sumberScanner
class ').StringTokenizer selalu ada di sana. Ini adalah yang tercepat dari semuanya, tetapi idiom seperti enumerasi mungkin tidak terlihat seanggun yang lain.
perpecahan muncul di JDK 1.4. Lebih lambat daripada tokenizer tetapi lebih mudah digunakan, karena dapat dipanggil dari kelas String.
Pemindai berada di JDK 1.5. Ini adalah yang paling fleksibel dan mengisi jeda panjang pada Java API untuk mendukung yang setara dengan keluarga fungsi Cs scanf yang terkenal.
sumber
Jika Anda memiliki objek String yang ingin Anda tokenize, nikmatilah menggunakan metode split String atas StringTokenizer. Jika Anda mem-parsing data teks dari sumber di luar program Anda, seperti dari file, atau dari pengguna, di situlah Scanner berguna.
sumber
Split lambat, tapi tidak selambat Scanner. StringTokenizer lebih cepat daripada split. Namun, saya menemukan bahwa saya dapat memperoleh dua kali lipat kecepatan, dengan memperdagangkan beberapa fleksibilitas, untuk mendapatkan peningkatan kecepatan, yang saya lakukan di JFastParser https://github.com/hughperkins/jfastparser
Menguji string yang berisi satu juta ganda:
sumber
String.split tampaknya jauh lebih lambat daripada StringTokenizer. Satu-satunya keuntungan dengan split adalah Anda mendapatkan berbagai token. Anda juga dapat menggunakan ekspresi reguler apa pun secara terpisah. org.apache.commons.lang.StringUtils memiliki metode split yang bekerja jauh lebih cepat daripada salah satu dari dua yaitu. StringTokenizer atau String.split. Namun pemanfaatan CPU untuk ketiganya hampir sama. Jadi kita juga memerlukan metode yang kurang intensif CPU, yang saya masih belum dapat menemukannya.
sumber
Baru-baru ini saya melakukan beberapa percobaan tentang kinerja buruk String.split () dalam situasi yang sangat sensitif terhadap kinerja. Anda mungkin menemukan ini berguna.
http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr
Intinya adalah bahwa String.split () mengkompilasi pola Ekspresi Reguler setiap kali dan dengan demikian dapat memperlambat program Anda, dibandingkan dengan jika Anda menggunakan objek Pola yang dikompilasi dan menggunakannya secara langsung untuk beroperasi pada String.
sumber
Untuk skenario default, saya akan menyarankan Pattern.split () juga tetapi jika Anda membutuhkan kinerja maksimum (terutama pada Android semua solusi yang saya uji cukup lambat) dan Anda hanya perlu dipisah dengan satu karakter, saya sekarang menggunakan metode saya sendiri:
Gunakan "abc" .toCharArray () untuk mendapatkan array char untuk sebuah String. Sebagai contoh:
sumber
Satu perbedaan penting adalah bahwa baik String.split () dan Scanner dapat menghasilkan string kosong tetapi StringTokenizer tidak pernah melakukannya.
Sebagai contoh:
Keluaran:
Ini karena pembatas untuk String.split () dan Scanner.useDelimiter () bukan hanya string, tetapi ekspresi reguler. Kita dapat mengganti pembatas "" dengan "+" pada contoh di atas untuk membuat mereka berperilaku seperti StringTokenizer.
sumber
String.split () berfungsi sangat baik tetapi memiliki batasannya sendiri, seperti jika Anda ingin membagi string seperti yang ditunjukkan di bawah ini berdasarkan simbol pipa tunggal atau ganda (|), itu tidak berfungsi. Dalam situasi ini Anda dapat menggunakan StringTokenizer.
ABC | IJK
sumber