Bagaimana untuk memeriksa apakah String numerik di Jawa
Bagaimana anda akan memeriksa apakah String adalah angka sebelum parsing itu?
833
39
Bagaimana anda akan memeriksa apakah String adalah angka sebelum parsing itu?
Hal ini umumnya dilakukan dengan sederhana user-defined function (yaitu Roll-anda-sendiri "isNumeric" fungsi).
Sesuatu seperti:
Namun, jika anda're memanggil fungsi ini banyak, dan anda mengharapkan banyak dari pemeriksaan gagal karena tidak menjadi nomor maka kinerja dari mekanisme ini tidak akan menjadi besar, karena anda're mengandalkan pengecualian dilemparkan untuk setiap kegagalan yang cukup mahal operasi.
Alternatif pendekatan yang mungkin untuk menggunakan ekspresi reguler untuk memeriksa validitas menjadi nomor:
Hati-hati dengan RegEx di atas mekanisme, meskipun, karena itu akan gagal jika anda're menggunakan non-arab digit (yaitu angka selain 0 sampai 9). Hal ini karena "\d" bagian dari RegEx yang hanya akan pertandingan [0-9] dan efektif isn't internasional numerik sadar. (Terima kasih untuk OregonGhost untuk menunjukkan ini!)
Atau bahkan alternatif lain adalah dengan menggunakan Java's built-in java.teks.NumberFormat objek untuk melihat jika, setelah parsing string parser posisi di akhir string. Jika sudah, kita dapat mengasumsikan seluruh string numerik:
Dengan Apache Commons Lang 3.5 dan di atas:
NumberUtils.isCreatable
atauStringUtils.isNumeric
.Dengan Apache Commons Lang 3.4 dan di bawah ini:
NumberUtils.isNumber
atauStringUtils.isNumeric
.Anda juga dapat menggunakan
StringUtils.isNumericSpace
yang mengembalikantrue
untuk string kosong dan mengabaikan internal spasi dalam string. Cara lain adalah dengan menggunakanStringUtils.isParsable
yang pada dasarnya pemeriksaan jumlah ini dapat diuraikan menurut Jawa. (Terkait javadocs mengandung detil contoh-contoh untuk masing-masing metode.)jika anda berada di android, maka anda harus menggunakan:
dokumentasi dapat ditemukan di sini
keep it simple. sebagian besar orang dapat "re-program" (hal yang sama).
Seperti @CraigTP telah disebutkan dalam jawaban yang sangat baik, saya juga memiliki kinerja yang sama menyangkut menggunakan Pengecualian untuk menguji apakah string numerik atau tidak. Jadi saya akhirnya membelah string dan menggunakan
jawa.lang.Karakter.isDigit()
.Menurut Awal,
Karakter.isDigit(char)
dengan benar akan mengakui non-Latin digit. Kinerja-bijaksana, saya pikir yang sederhana N jumlah perbandingan di mana N adalah jumlah karakter dalam string akan lebih komputasi efisien daripada melakukan regex yang cocok.UPDATE: Seperti yang ditunjukkan oleh Jean-François Corbett di komentar, kode di atas hanya akan memvalidasi bilangan bulat positif, yang mencakup sebagian besar saya gunakan kasus. Di bawah ini adalah update kode yang benar memvalidasi angka desimal sesuai dengan standar lokal yang digunakan di sistem anda, dengan asumsi bahwa pemisah desimal hanya terjadi sekali dalam string.
Jawa 8 ekspresi lambda.
Google's Jambu perpustakaan menyediakan baik penolong metode untuk melakukan hal ini:
Int.tryParse
. Anda menggunakannya sepertiInteger.parseInt
tapi itu kembalinull
daripada melempar Pengecualian jika string tidak mengurai ke integer yang valid. Perhatikan bahwa ia mengembalikan Integer, tidak int, jadi anda harus mengkonversi/autobox kembali ke int.Contoh:
Namun, seperti dari rilis saat ini -- Jambu r11 -- itu masih ditandai @Beta.
Aku ingin't diperbandingkan itu. Melihat kode sumber ada beberapa overhead dari banyak kewarasan memeriksa tetapi pada akhirnya mereka menggunakan
Karakter.digit(string.charAt(idx))
, yang mirip, tapi sedikit berbeda dari, jawaban dari @Ibrahim di atas. Tidak ada pengecualian penanganan overhead bawah selimut dalam pelaksanaannya.Jangan menggunakan Pengecualian untuk memvalidasi nilai-nilai anda. Gunakan Util libs bukan seperti apache NumberUtils:
Edit:
Harap perhatikan bahwa, jika string dimulai dengan 0, NumberUtils akan menafsirkan nilai sebagai heksadesimal.
Mengapa semua orang mendorong untuk pengecualian/regex solusi?
Sementara aku dapat memahami sebagian besar orang baik-baik saja dengan menggunakan try/catch, jika anda ingin melakukannya sering... itu bisa sangat melelahkan.
Apa yang saya lakukan di sini adalah mengambil regex, yang parseNumber() metode, dan array mencari metode untuk melihat yang mana yang paling efisien. Kali ini, saya hanya melihat angka integer.
Hasil dalam kecepatan yang saya punya adalah:
Disclaimer: saya'm tidak mengklaim metode ini 100% dioptimalkan, mereka're hanya untuk demonstrasi data
Pengecualian tidak jika dan hanya jika nomor 4 karakter atau kurang, dan setiap string selalu nomor... dalam hal ini, mengapa bahkan memiliki cek?
Dalam jangka pendek, hal ini sangat menyakitkan jika anda menjalankan ke nomor tidak valid sering dengan mencoba menangkap, yang masuk akal. Aturan penting yang selalu saya ikuti adalah jangan PERNAH menggunakan try/catch untuk alur program. Ini adalah contoh mengapa.
Menariknya, sederhana jika char <0 || >9 sangat sederhana untuk menulis, mudah untuk diingat (dan harus bekerja dalam beberapa bahasa) dan berhasil merebut hampir semua skenario pengujian.
Satu-satunya downside adalah bahwa saya'm menebak bilangan Bulat.parseInt() akan menangani non-ASCII angka, sedangkan array mencari metode tidak.
Bagi mereka bertanya-tanya mengapa aku mengatakan itu's mudah untuk mengingat karakter array satu, jika anda tahu ada's tidak ada tanda-tanda negatif, anda dapat dengan mudah pergi dengan sesuatu yang kental seperti ini:
Terakhir, sebagai catatan akhir, saya ingin tahu tentang assigment operator di diterima misalnya dengan semua suara hingga. Menambahkan dalam tugas
tidak hanya berguna karena anda don't bahkan menggunakan nilai, tetapi limbah pengolahan waktu dan meningkatkan runtime oleh beberapa nanodetik (yang menyebabkan 100-200 ms peningkatan dalam tes). Saya dapat't melihat mengapa seseorang tidak akan melakukan itu karena itu benar-benar bekerja ekstra untuk mengurangi kinerja.
Anda'd pikir itu akan dioptimalkan keluar... meskipun mungkin aku harus memeriksa bytecode dan melihat apa yang penyusun lakukan. Itu doesn't menjelaskan mengapa hal itu selalu muncul sebagai lebih panjang bagi saya meskipun jika entah bagaimana dioptimalkan keluar... oleh karena itu saya bertanya-tanya apa yang's terjadi. Sebagai catatan: Dengan lebih panjang, maksud saya menjalankan tes untuk 10000000 iterasi, dan menjalankan program itu beberapa kali (10x+) selalu menunjukkan untuk menjadi lebih lambat.
EDIT: Diperbarui tes untuk Karakter.isDigit()
CraigTP's regular expression (ditampilkan di atas) menghasilkan positif palsu. E. g. "23y4" akan dihitung sebagai jumlah karena '.' cocok dengan semua karakter yang bukan titik desimal.
Juga akan menolak setiap nomor dengan terkemuka '+'
Alternatif yang menghindari dua masalah kecil adalah
Kita dapat mencoba mengganti semua angka dari string tertentu dengan ("") yaitu ruang kosong dan jika setelah itu panjang dari string adalah nol, maka kita dapat mengatakan bahwa mengingat string hanya berisi angka-angka. [Jika anda menemukan jawaban ini bermanfaat maka jangan menganggap pemungutan suara itu] Contoh:
Anda dapat menggunakan
NumberFormat#parse
:Jika anda menggunakan java untuk mengembangkan aplikasi Android, anda bisa menggunakan TextUtils.isDigitsOnly fungsi.
Berikut ini adalah jawaban saya untuk masalah ini.
Menangkap semua kemudahan metode yang dapat anda gunakan untuk mengurai String apapun dengan setiap jenis parser:
isParsable(Objek parser, String str)
. Parser dapat menjadiKelas
atauobjek
. Ini juga akan memungkinkan anda untuk menggunakan kustom parser anda've tertulis dan harus bekerja untuk selama-lamanya skenario, misalnya:Berikut ini's my kode lengkap dengan metode deskripsi.
Pengecualian adalah mahal, tetapi dalam kasus ini RegEx memakan waktu lebih lama. Kode di bawah ini menunjukkan sebuah tes sederhana dari dua fungsi -- satu menggunakan pengecualian dan satu menggunakan regex. Pada mesin RegEx versi 10 kali lebih lambat dari pengecualian.
Berikut adalah contoh lain upgrade "CraigTP" regex yang cocok dengan lebih validasi.
// silahkan cek di bawah kode
Baik melakukan pendekatan menghindari coba-menangkap dan penanganan negatif angka dan notasi ilmiah.
Untuk pertandingan hanya positif base-sepuluh bilangan bulat, yang hanya berisi ASCII digit, gunakan:
Berikut adalah kelas saya untuk mengecek apakah suatu string numerik. Ini juga perbaikan numerik string:
Fitur:
Di sini anda pergi...