Anda juga dapat menggunakan StringUtils.isNumericSpaceyang mengembalikan truestring kosong dan mengabaikan spasi internal dalam string. Cara lain adalah dengan menggunakan NumberUtils.isParsableyang pada dasarnya memeriksa nomor yang dapat diuraikan menurut Java. (The javadocs yang ditautkan berisi contoh terperinci untuk setiap metode.)
StringUtils.isNumeric()mungkin tidak akan sesuai di sini karena hanya memeriksa apakah string adalah urutan digit. Akan baik untuk sebagian besar int tetapi tidak demikian untuk angka dengan desimal, pemisah grup, dll.
Jeff Mercado
42
temukan kembali roda karena Anda tidak menyertakan seluruh perpustakaan karena Anda memerlukan fungsi 3 baris di satu tempat.
dalvarezmartinez1
12
Apakah benar-benar layak menambahkan seluruh perpustakaan untuk fitur ini? Jelas jika itu digunakan dengan hal-hal lain yang hebat, tetapi mungkin berlebihan mengingat orang telah menyelesaikan ini dalam satu baris kode.
Air
7
Tidak bekerja dengan yang negatif. Dan setengah dari semua angka negatif, jadi .....
Paul Draper
6
@ PaulDraper: Anda benar, StringUtilstidak mendukung tanda-tanda terkemuka tetapi Anda harus memeriksa NumberUtils.isCreatable, ini mendukung negatif dengan benar.
palacsint
904
Ini umumnya dilakukan dengan fungsi sederhana yang ditentukan pengguna (yaitu fungsi Roll-your-own "isNumeric").
Namun, jika Anda sering memanggil fungsi ini, dan Anda berharap banyak cek gagal karena tidak menjadi angka maka kinerja mekanisme ini tidak akan bagus, karena Anda mengandalkan pengecualian yang dilemparkan untuk setiap kegagalan, yang merupakan operasi yang cukup mahal.
Pendekatan alternatif mungkin menggunakan ekspresi reguler untuk memeriksa validitas menjadi nomor:
publicstaticboolean isNumeric(String str){return str.matches("-?\\d+(\\.\\d+)?");//match a number with optional '-' and decimal.}
Berhati-hatilah dengan mekanisme RegEx di atas, karena akan gagal jika Anda menggunakan angka non-Arab (yaitu angka selain 0 hingga 9). Ini karena bagian "\ d" dari RegEx hanya akan cocok dengan [0-9] dan secara efektif tidak sadar secara numerik secara internasional. (Terima kasih kepada OregonGhost untuk menunjukkan ini!)
Atau bahkan alternatif lain adalah dengan menggunakan Java.text.NumberFormat objek bawaan Java untuk melihat apakah, setelah mengurai string posisi parser berada di akhir string. Jika ya, kita dapat menganggap seluruh string adalah numerik:
Apakah di Java Regex hanya cocok dengan angka latin? Jika seperti .NET regexes, Anda akan mengalami masalah dengan digit lainnya (mis. Bahasa Arab), seperti dijelaskan di sini: blogs.msdn.com/oldnewthing/archive/2004/03/09/86555.aspx
OregonGhost
3
solusi numberFormatter mungkin hanya sedikit lebih baik daripada menangkap yang NumberFormatException. Saya menduga cara terbaik adalah menggunakan regex satu.
Chii
11
Perhatikan bahwa .dalam regex Anda akan cocok dengan karakter apa pun, bukan hanya karakter pemisah desimal.
jqno
9
+1 untuk menyadari biaya percobaan / tangkapan. Ini sebenarnya pendekatan yang mengerikan untuk digunakan dalam jangka panjang untuk penggunaan berulang, tapi kami benar-benar terjebak dengan itu di Jawa.
demongolem
5
Perhatikan bahwa tidak ada hal-hal seperti "angka latin", dan angka 0-9 sebenarnya adalah angka Arab. Orang-orang mungkin akrab dengan angka Romawi, yang digunakan oleh orang-orang yang berbicara bahasa Latin, dalam bentuk I, II, III, IV, V, VI, dll. En.wikipedia.org/wiki/Arabic_numerals ; en.wikipedia.org/wiki/Roman_numerals
dantiston
152
Jika Anda menggunakan Android, maka Anda harus menggunakan:
@ kape123 :) yakin "123.456" tidak mengandung digit.
Ahmed Alejo
8
Catatan: ini menghasilkan NPE untuk input nol. Juga, tidak bekerja dengan angka atau desimal negatif.
gMale
2
Saya suka itu!! Saya pikir ini mutlak untuk angka. Bukan untuk .,-
illusionJJ
Inilah yang saya cari. Sesuatu yang sederhana untuk memeriksa hanya angka 0-9. Saya menetapkan filter dalam deklarasi EditText saya, tetapi untuk berjaga-jaga jika bisa diubah atau diganti, ada baiknya juga melakukan pemeriksaan terprogram yang sederhana.
Anda dapat menggunakan referensi metode, juga: someString.chars (). AllMatch (Character :: isDigit)
Wienczny
3
Bagus tapi tetap saja menciptakan kembali roda karena hampir semua "solusi" di sini. Juga, gagal pada 'null' (karena hampir semua yang lain).
qben
8
Jawaban ini ringkas, sederhana dan mudah dibaca. Anda hampir dapat membacanya seperti bahasa Inggris - "karakter semua angka cocok". Itu tidak memerlukan perpustakaan pihak ketiga. Itu tidak menggunakan pengecualian dalam kasus yang tidak biasa. Ini harus menjadi jawaban yang diterima.
Andy Thomas
14
Apa yang akan dihasilkan untuk "-1"?
Balázs Németh
2
Bukan jawaban yang benar. String numerik dapat memiliki karakter non-numerik (mis. "." Atau "-") dan masih numerik dengan sempurna. Misalnya 0,5, -1, dan 1.000 semuanya akan gagal dengan jawaban ini, namun semuanya numerik.
Simeon G
126
Seperti @CraigTP telah menyebutkan dalam jawaban yang sangat baik, saya juga memiliki masalah kinerja yang serupa dalam menggunakan Pengecualian untuk menguji apakah string tersebut numerik atau tidak. Jadi saya akhirnya memisahkan string dan menggunakan java.lang.Character.isDigit().
publicstaticboolean isNumeric(String str){for(char c : str.toCharArray()){if(!Character.isDigit(c))returnfalse;}returntrue;}
Menurut Javadoc , Character.isDigit(char)akan dengan benar mengenali angka non-Latin. Dari segi kinerja, saya pikir perbandingan N sederhana di mana N adalah jumlah karakter dalam string akan lebih efisien secara komputasi daripada melakukan pencocokan regex.
UPDATE: Seperti yang ditunjukkan oleh Jean-François Corbett dalam komentar, kode di atas hanya akan memvalidasi bilangan bulat positif, yang mencakup sebagian besar kasus penggunaan saya. Di bawah ini adalah kode yang diperbarui yang memvalidasi angka desimal dengan benar sesuai dengan lokal default yang digunakan dalam sistem Anda, dengan asumsi bahwa pemisah desimal hanya terjadi satu kali dalam string.
publicstaticboolean isStringNumeric(String str ){DecimalFormatSymbols currentLocaleSymbols =DecimalFormatSymbols.getInstance();char localeMinusSign = currentLocaleSymbols.getMinusSign();if(!Character.isDigit( str.charAt(0))&& str.charAt(0)!= localeMinusSign )returnfalse;boolean isDecimalSeparatorFound =false;char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();for(char c : str.substring(1).toCharArray()){if(!Character.isDigit( c )){if( c == localeDecimalSeparator &&!isDecimalSeparatorFound ){
isDecimalSeparatorFound =true;continue;}returnfalse;}}returntrue;}
Bukankah pemisah desimal juga menyebabkan ini gagal?
Jean-François Corbett
1
@ Jean-FrançoisCorbett: Bagus, saya telah memperbarui kode dengan yang lebih baru yang menerima pemisah desimal.
Ibrahim Arief
2
Apakah tanda -ve gagal fungsi ini?
java_mouse
3
Memanggil toCharArray()akan membuat salinan array di objek String karena String tidak berubah. Mungkin lebih cepat menggunakan charAt(int index)metode pada objek String secara langsung.
Mike Kucera
2
Akan menghasilkan StringIndexOutOfBoundsExceptionketika melewati string dengan panjang 0. Dapat diperbaiki denganif(str.length() == 0) return false;
samgak
43
Perpustakaan Guava Google menyediakan metode pembantu yang baik untuk melakukan hal ini: Ints.tryParse. Anda menggunakannya seperti Integer.parseInttetapi mengembalikan nulldaripada melemparkan Pengecualian jika string tidak mem-parsing ke integer yang valid. Perhatikan bahwa ia mengembalikan Integer, bukan int, jadi Anda harus mengonversi / autobox kembali ke int.
Namun, pada rilis saat ini - Jambu r11 - masih ditandai @Beta.
Saya belum membandingkannya. Melihat kode sumber ada beberapa overhead dari banyak pemeriksaan kewarasan tetapi pada akhirnya mereka menggunakan Character.digit(string.charAt(idx)), mirip, tetapi sedikit berbeda dari, jawaban dari @Ibrahim di atas. Tidak ada pengecualian menangani overhead di bawah penutup dalam implementasinya.
Jawaban yang diterima, tiga tahun sebelumnya, sudah dibahas Number.isNumber().
Andy Thomas
Saya kira tidak. Itu diperbarui atau op mengubah jawaban yang diterima. Saya ingat jawaban yang diterima tidak mencakup NumberUtils, itulah sebabnya saya menambahkan jawaban saya. Tapi terima kasih atas komentarnya
Goot
2
@ Goot - Sejarah jawaban yang diterima menunjukkan bahwa Number.isNumber()hadir dari versi pertama jawaban, tertanggal 24 Sep 12 pada 17:01.
Andy Thomas
@Boot, ini cukup bagus karena juga mencakup pemeriksaan nilai desimal, tidak seperti StringUtils.
Heena Hussain
24
Mengapa semua orang mendorong solusi pengecualian / regex?
Walaupun saya bisa mengerti kebanyakan orang baik-baik saja dengan menggunakan try / catch, jika Anda ingin sering melakukannya ... itu bisa sangat melelahkan.
Apa yang saya lakukan di sini adalah mengambil regex, metode parseNumber (), dan metode pencarian array untuk melihat mana yang paling efisien. Kali ini, saya hanya melihat angka integer.
publicstaticboolean isNumericRegex(String str){if(str ==null)returnfalse;return str.matches("-?\\d+");}publicstaticboolean isNumericArray(String str){if(str ==null)returnfalse;char[] data = str.toCharArray();if(data.length <=0)returnfalse;int index =0;if(data[0]=='-'&& data.length >1)
index =1;for(; index < data.length; index++){if(data[index]<'0'|| data[index]>'9')// Character.isDigit() can go here too.returnfalse;}returntrue;}publicstaticboolean isNumericException(String str){if(str ==null)returnfalse;try{/* int i = */Integer.parseInt(str);}catch(NumberFormatException nfe){returnfalse;}returntrue;}
Hasil dalam kecepatan yang saya dapatkan adalah:
Done with:for(int i =0; i <10000000; i++)...With only valid numbers ("59815833" and "-59815833"):Array numeric took 395.808192 ms [39.5808192 ns each]Regex took 2609.262595 ms [260.9262595 ns each]Exception numeric took 428.050207 ms [42.8050207 ns each]// Negative signArray numeric took 355.788273 ms [35.5788273 ns each]Regex took 2746.278466 ms [274.6278466 ns each]Exception numeric took 518.989902 ms [51.8989902 ns each]// Single value ("1")Array numeric took 317.861267 ms [31.7861267 ns each]Regex took 2505.313201 ms [250.5313201 ns each]Exception numeric took 239.956955 ms [23.9956955 ns each]// With Character.isDigit()Array numeric took 400.734616 ms [40.0734616 ns each]Regex took 2663.052417 ms [266.3052417 ns each]Exception numeric took 401.235906 ms [40.1235906 ns each]With invalid characters ("5981a5833" and "a"):Array numeric took 343.205793 ms [34.3205793 ns each]Regex took 2608.739933 ms [260.8739933 ns each]Exception numeric took 7317.201775 ms [731.7201775 ns each]// With a single character ("a")Array numeric took 291.695519 ms [29.1695519 ns each]Regex took 2287.25378 ms [228.725378 ns each]Exception numeric took 7095.969481 ms [709.5969481 ns each]Withnull:Array numeric took 214.663834 ms [21.4663834 ns each]Regex took 201.395992 ms [20.1395992 ns each]Exception numeric took 233.049327 ms [23.3049327 ns each]Exception numeric took 6603.669427 ms [660.3669427 ns each]if there is no if/null check
Penafian: Saya tidak mengklaim metode ini 100% dioptimalkan, mereka hanya untuk demonstrasi data
Pengecualian dimenangkan jika dan hanya jika jumlahnya 4 karakter atau kurang, dan setiap string selalu angka ... dalam hal ini, mengapa bahkan memiliki cek?
Singkatnya, sangat menyakitkan jika Anda sering menemukan nomor yang tidak valid dengan try / catch, yang masuk akal. Aturan penting yang selalu saya ikuti adalah JANGAN PERNAH menggunakan try / catch untuk aliran program . Ini adalah contoh mengapa.
Menariknya, simpel jika char <0 || > 9 sangat sederhana untuk ditulis, mudah diingat (dan harus bekerja dalam berbagai bahasa) dan memenangkan hampir semua skenario pengujian.
Satu-satunya downside adalah bahwa saya menebak Integer.parseInt () mungkin menangani angka non ASCII, sedangkan metode pencarian array tidak.
Bagi mereka yang bertanya-tanya mengapa saya mengatakan mudah untuk mengingat satu array karakter, jika Anda tahu tidak ada tanda-tanda negatif, Anda dapat dengan mudah lolos dengan sesuatu yang kental seperti ini:
publicstaticboolean isNumericArray(String str){if(str ==null)returnfalse;for(char c : str.toCharArray())if(c <'0'|| c >'9')returnfalse;returntrue;
Terakhir sebagai catatan terakhir, saya ingin tahu tentang operator asistensi dalam contoh yang diterima dengan semua suara di atas. Menambahkan penugasan
double d =Double.parseDouble(...)
tidak hanya tidak berguna karena Anda bahkan tidak menggunakan nilai, tetapi juga membuang-buang waktu pemrosesan dan meningkatkan runtime oleh beberapa nanodetik (yang menyebabkan peningkatan 100-200 ms dalam tes). Saya tidak dapat melihat mengapa ada orang yang melakukan itu karena ini adalah pekerjaan tambahan untuk mengurangi kinerja.
Anda akan berpikir bahwa itu akan dioptimalkan ... meskipun mungkin saya harus memeriksa bytecode dan melihat apa yang dilakukan oleh kompiler. Itu tidak menjelaskan mengapa itu selalu tampak lebih panjang bagi saya meskipun jika entah bagaimana dioptimalkan keluar ... karena itu saya bertanya-tanya apa yang terjadi. Sebagai catatan: Secara lebih panjang, maksud saya menjalankan tes untuk 10.000.000 iterasi, dan menjalankan program itu beberapa kali (10x +) selalu menunjukkan itu lebih lambat.
Bukankah ini mengkompilasi ekspresi reguler baru setiap waktu? Itu tidak terlihat sangat efisien.
Samuel Edwin Ward
1
@SamuelEdwinWard Itulah seluruh alasan saya membuat posting ini ... contoh regex menggunakan jawaban yang diberikan orang lain dan menunjukkan betapa tidak efisiennya itu. Bahkan jika Anda mencoba regex dengan pra-kompilasi sebelumnya dan hanya menggunakan itu, perbedaan waktu adalah: 2587 ms untuk regex yang saya posting dari orang lain yang disediakan, 950 ms ketika dikompilasi sebelumnya, 144 ms ketika melakukannya sebagai array numerik (untuk 1 mil iterasi string yang sama). Mengompilasi sebelumnya tentu saja akan membantu, tetapi sayangnya itu masih cukup rendah dengan cara array ... kecuali ada beberapa optimasi gila yang saya tidak tahu.
Air
Percaya bahwa Regex membuat segalanya lebih cepat hampir merupakan kekeliruan. Jika ini adalah satu pencarian, ya, saya mengerti ... tapi saya perhatikan kode yang ditulis secara efisien sebenarnya mengalahkan regex yang cukup mengejutkan Anda! Pos luar biasa @Water
Ekspresi reguler CraigTP (ditampilkan di atas) menghasilkan beberapa positif palsu. Misalnya "23y4" akan dihitung sebagai angka karena '.' cocok dengan karakter apa pun bukan titik desimal.
Juga akan menolak nomor apa pun dengan '+' yang memimpin
Alternatif yang menghindari dua masalah kecil ini adalah
ini akan kembali trueuntuk plus "+"atau minus tunggal "-", dan falseuntuk"0."
user85421
Bagus menangkap plus atau minus tunggal. Apakah "0." angka yang valid?
user872985
"0."valid untuk Double.parseDouble()dan merupakan literal yang sah menurut JLS ( §3.10.2 )!
user85421
Membuat ekspresi reguler juga mahal. Ekspresi reguler harus dibuat sekali dan digunakan kembali
Daniel Nuriyev
1
Anda harus mengubahnya kematches("-?\\d+([.]\\d+)?")
Bobs
14
Kita dapat mencoba mengganti semua angka dari string yang diberikan dengan ("") yaitu ruang kosong dan jika setelah itu panjang string adalah nol maka kita dapat mengatakan bahwa string yang diberikan hanya berisi angka. [Jika Anda menemukan jawaban ini bermanfaat maka silakan pertimbangkan untuk memilihnya] Contoh:
boolean isNumber(String str){if(str.length()==0)returnfalse;//To check if string is emptyif(str.charAt(0)=='-')
str = str.replaceFirst("-","");// for handling -ve numbersSystem.out.println(str);
str = str.replaceFirst("\\.","");//to check if it contains more than one decimal pointsif(str.length()==0)returnfalse;// to check if it is empty string after removing -ve sign and decimal pointSystem.out.println(str);return str.replaceAll("[0-9]","").length()==0;}
Jelas tidak berlaku untuk semua bentuk angka, tetapi inilah suara positif untuk berpikir secara berbeda ... jika pikiran aslinya adalah milik Anda, itu adalah.
Sebuah menangkap semua metode kenyamanan yang dapat Anda gunakan untuk mengurai setiap String dengan semua jenis parser: isParsable(Object parser, String str). Parser dapat berupa a Classatau a object. Ini juga akan memungkinkan Anda untuk menggunakan parser khusus yang Anda tulis dan harus berfungsi untuk skenario sebelumnya, misalnya:
isParsable(Integer.class,"11");
isParsable(Double.class,"11.11");Object dateFormater =new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
isParsable(dateFormater,"2001.07.04 AD at 12:08:56 PDT");
Ini kode saya lengkap dengan deskripsi metode.
import java.lang.reflect.*;/**
* METHOD: isParsable<p><p>
*
* This method will look through the methods of the specified <code>from</code> parameter
* looking for a public method name starting with "parse" which has only one String
* parameter.<p>
*
* The <code>parser</code> parameter can be a class or an instantiated object, eg:
* <code>Integer.class</code> or <code>new Integer(1)</code>. If you use a
* <code>Class</code> type then only static methods are considered.<p>
*
* When looping through potential methods, it first looks at the <code>Class</code> associated
* with the <code>parser</code> parameter, then looks through the methods of the parent's class
* followed by subsequent ancestors, using the first method that matches the criteria specified
* above.<p>
*
* This method will hide any normal parse exceptions, but throws any exceptions due to
* programmatic errors, eg: NullPointerExceptions, etc. If you specify a <code>parser</code>
* parameter which has no matching parse methods, a NoSuchMethodException will be thrown
* embedded within a RuntimeException.<p><p>
*
* Example:<br>
* <code>isParsable(Boolean.class, "true");<br>
* isParsable(Integer.class, "11");<br>
* isParsable(Double.class, "11.11");<br>
* Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");<br>
* isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");<br></code>
* <p>
*
* @param parser The Class type or instantiated Object to find a parse method in.
* @param str The String you want to parse
*
* @return true if a parse method was found and completed without exception
* @throws java.lang.NoSuchMethodException If no such method is accessible
*/publicstaticboolean isParsable(Object parser,String str){Class theClass =(parser instanceofClass?(Class)parser: parser.getClass());boolean staticOnly =(parser == theClass), foundAtLeastOne =false;Method[] methods = theClass.getMethods();// Loop over methodsfor(int index =0; index < methods.length; index++){Method method = methods[index];// If method starts with parse, is public and has one String parameter.// If the parser parameter was a Class, then also ensure the method is static. if(method.getName().startsWith("parse")&&(!staticOnly ||Modifier.isStatic(method.getModifiers()))&&Modifier.isPublic(method.getModifiers())&&
method.getGenericParameterTypes().length ==1&&
method.getGenericParameterTypes()[0]==String.class){try{
foundAtLeastOne =true;
method.invoke(parser, str);returntrue;// Successfully parsed without exception}catch(Exception exception){// If invoke problem, try a different method/*if(!(exception instanceof IllegalArgumentException) &&
!(exception instanceof IllegalAccessException) &&
!(exception instanceof InvocationTargetException))
continue; // Look for other parse methods*/// Parse method refuses to parse, look for another different methodcontinue;// Look for other parse methods}}}// No more accessible parse method could be found.if(foundAtLeastOne)returnfalse;elsethrownewRuntimeException(newNoSuchMethodException());}/**
* METHOD: willParse<p><p>
*
* A convienence method which calls the isParseable method, but does not throw any exceptions
* which could be thrown through programatic errors.<p>
*
* Use of {@link #isParseable(Object, String) isParseable} is recommended for use so programatic
* errors can be caught in development, unless the value of the <code>parser</code> parameter is
* unpredictable, or normal programtic exceptions should be ignored.<p>
*
* See {@link #isParseable(Object, String) isParseable} for full description of method
* usability.<p>
*
* @param parser The Class type or instantiated Object to find a parse method in.
* @param str The String you want to parse
*
* @return true if a parse method was found and completed without exception
* @see #isParseable(Object, String) for full description of method usability
*/publicstaticboolean willParse(Object parser,String str){try{return isParsable(parser, str);}catch(Throwable exception){returnfalse;}}
Pendekatan yang berperforma baik menghindari try-catch dan menangani angka negatif dan notasi ilmiah.
Pattern PATTERN =Pattern.compile("^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$");publicstaticboolean isNumeric(String value ){return value !=null&& PATTERN.matcher( value ).matches();}
Ini kelas saya untuk memeriksa apakah sebuah string adalah angka. Itu juga memperbaiki string numerik:
Fitur:
Menghapus nol yang tidak perlu ["12.0000000" -> "12"]
Menghapus nol yang tidak perlu ["12.0580000" -> "12.058"]
Menghapus karakter non numerik ["12.00sdfsdf00" -> "12"]
Menangani nilai string negatif ["-12,020000" -> "-12,02"]
Menghapus banyak titik ["-12.0.20.000" -> "-12.02"]
Tidak ada perpustakaan tambahan, hanya Java standar
Ini dia ...
publicclassNumUtils{/**
* Transforms a string to an integer. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/staticString makeToInteger(String str){String s = str;double d;
d =Double.parseDouble(makeToDouble(s));int i =(int)(d +0.5D);String retStr =String.valueOf(i);System.out.printf(retStr +" ");return retStr;}/**
* Transforms a string to an double. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/staticString makeToDouble(String str){Boolean dotWasFound =false;String orgStr = str;String retStr;int firstDotPos =0;Boolean negative =false;//check if str is nullif(str.length()==0){
str="0";}//check if first sign is "-"if(str.charAt(0)=='-'){
negative =true;}//check if str containg any number or else set the string to '0'if(!str.matches(".*\\d+.*")){
str ="0";}//Replace ',' with '.' (for some european users who use the ',' as decimal separator)
str = str.replaceAll(",",".");
str = str.replaceAll("[^\\d.]","");//Removes the any second dotsfor(int i_char =0; i_char < str.length(); i_char++){if(str.charAt(i_char)=='.'){
dotWasFound =true;
firstDotPos = i_char;break;}}if(dotWasFound){String befDot = str.substring(0, firstDotPos +1);String aftDot = str.substring(firstDotPos +1, str.length());
aftDot = aftDot.replaceAll("\\.","");
str = befDot + aftDot;}//Removes zeros from the beginingdouble uglyMethod =Double.parseDouble(str);
str =String.valueOf(uglyMethod);//Removes the .0
str = str.replaceAll("([0-9])\\.0+([^0-9]|$)","$1$2");
retStr = str;if(negative){
retStr ="-"+retStr;}return retStr;}staticboolean isNumeric(String str){try{double d =Double.parseDouble(str);}catch(NumberFormatException nfe){returnfalse;}returntrue;}}
Pengecualian itu mahal, tetapi dalam hal ini RegEx membutuhkan waktu lebih lama. Kode di bawah ini menunjukkan tes sederhana dari dua fungsi - satu menggunakan pengecualian dan satu menggunakan regex. Di komputer saya, versi RegEx 10 kali lebih lambat dari pengecualian.
import java.util.Date;publicclassIsNumeric{publicstaticboolean isNumericOne(String s){return s.matches("-?\\d+(\\.\\d+)?");//match a number with optional '-' and decimal. }publicstaticboolean isNumericTwo(String s){try{Double.parseDouble(s);returntrue;}catch(Exception e){returnfalse;}}publicstaticvoid main(String[] args){String test ="12345.F";long before =newDate().getTime();for(int x=0;x<1000000;++x){//isNumericTwo(test);
isNumericOne(test);}long after =newDate().getTime();System.out.println(after-before);}}
Secara umum, saya pikir kode semacam ini akan digunakan untuk memeriksa hal-hal seperti input yang diketik. Dalam hal ini kecepatan bukanlah pertimbangan dan melakukan sesuatu yang jelek seperti melempar pengecualian untuk memeriksa nomor atau bukan-nomor adalah salah.
user872985
Mungkin tidak. Input yang diketik umumnya diperiksa oleh komponen UI di mana kesalahan dapat segera ditampilkan sebelum mengirimkan nilai. Mungkin lebih umum untuk memvalidasi string dari file teks input besar - di mana kinerja penting. Tujuan jawaban saya di sini adalah untuk menanggapi pernyataan "pengecualian lambat" dalam jawaban yang diterima. Regex yang kompleks jauh lebih mahal. Dan tidak ada "lemparan jelek" dalam kode saya sama sekali - hanya cara yang lebih cepat untuk mendeteksi pelanggaran. Dengan pendekatan check-first-then-menghitung Anda membuat dua lintasan melalui input: satu untuk memverifikasi dan satu lagi untuk dikonversi.
ChrisCantrell
5
// silakan periksa kode di bawah ini
publicstaticboolean isDigitsOnly(CharSequence str){finalint len = str.length();for(int i =0; i < len; i++){if(!Character.isDigit(str.charAt(i))){returnfalse;}}returntrue;}
Pertanyaannya mengatakan "numerik" yang dapat menyertakan nilai-nilai non-integer.
rghome
3
// only intpublicstaticboolean isNumber(int num){return(num >=48&& c <=57);// 0 - 9}// is type of number including . - e E publicstaticboolean isNumber(String s){boolean isNumber =true;for(int i =0; i < s.length()&& isNumber; i++){char c = s.charAt(i);
isNumber = isNumber &((c >='0'&& c <='9')||(c =='.')||(c =='e')||(c =='E')||(c ==''));}return isInteger;}// is type of number publicstaticboolean isInteger(String s){boolean isInteger =true;for(int i =0; i < s.length()&& isInteger; i++){char c = s.charAt(i);
isInteger = isInteger &((c >='0'&& c <='9'));}return isInteger;}publicstaticboolean isNumeric(String s){try{Double.parseDouble(s);returntrue;}catch(Exception e){returnfalse;}}
publicstaticboolean isNumericString(String input){boolean result =false;if(input !=null&& input.length()>0){char[] charArray = input.toCharArray();for(char c : charArray){if(c >='0'&& c <='9'){// it is a digit
result =true;}else{
result =false;break;}}}return result;}
Saya memodifikasi solusi CraigTP untuk menerima notasi ilmiah dan juga titik dan koma sebagai pemisah desimal
^-?\d+([,\.]\d+)?([eE]-?\d+)?$
contoh
var re =newRegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");
re.test("-6546");// true
re.test("-6546355e-4456");// true
re.test("-6546.355e-4456");// true, though debatable
re.test("-6546.35.5e-4456");// false
re.test("-6546.35.5e-4456.6");// false
Itu sebabnya saya menyukai pendekatan Try * di .NET. Selain metode Parse tradisional yang seperti Java, Anda juga memiliki metode TryParse. Saya tidak pandai sintaksis Java (parameter out?), Jadi tolong perlakukan yang berikut ini sebagai semacam pseudo-code. Seharusnya konsepnya jelas.
boolean parseInteger(String s, out int number){try{
number =Integer.parseInt(myString);returntrue;}catch(NumberFormatException e){returnfalse;}}
Pemakaian:
int num;if(parseInteger("23", out num)){// Do something with num.}
ya, tidak ada "parameter keluar" di Jawa dan karena pembungkus Integer tidak dapat diubah (dengan demikian tidak dapat digunakan sebagai referensi yang valid untuk menyimpan output), opsi idiomatis yang masuk akal akan mengembalikan objek Integer yang bisa menjadi nol jika mengurai gagal. Opsi yang lebih buruk adalah untuk melewatkan int [1] sebagai parameter output.
fortran
Ya, saya ingat diskusi tentang mengapa Java tidak memiliki parameter output. tetapi mengembalikan Integer (sebagai null, jika perlu) akan baik-baik saja, saya kira, meskipun saya tidak tahu tentang kinerja Java sehubungan dengan tinju / unboxing.
OregonGhost
4
Saya suka C # sebanyak orang berikutnya, tetapi tidak ada gunanya menambahkan potongan .NET C # kode untuk pertanyaan Java ketika fitur tidak ada di Jawa
Shane
Itu akan membuat masalah sonar jika Anda tidak mencatat pengecualian
jmhostalet
2
Parse itu (yaitu dengan Integer#parseInt) dan cukup menangkap pengecualian. =)
Untuk memperjelas: Fungsi parseInt memeriksa apakah ia dapat menguraikan nomor dalam kasus apa pun (jelas) dan jika Anda tetap ingin menguraikannya, Anda tidak akan mendapatkan kinerja yang terpukul dengan benar-benar melakukan parsing.
Jika Anda tidak ingin menguraikannya (atau menguraikannya sangat, sangat jarang), Anda tentu ingin melakukannya secara berbeda.
Saya telah menggambarkan beberapa kondisi untuk memeriksa angka dan desimal tanpa menggunakan API apa pun,
Periksa Perbaiki Panjang 1 digit angka
Character.isDigit(char)
Periksa nomor Fix Length (Asumsikan panjang 6)
String number ="132452";if(number.matches("([0-9]{6})"))System.out.println("6 digits number identified");
Periksa nomor Panjang yang Bervariasi antara (Asumsikan panjang 4 hingga 6)
// {n,m} n <= length <= mString number ="132452";if(number.matches("([0-9]{4,6})"))System.out.println("Number Identified between 4 to 6 length");String number ="132";if(!number.matches("([0-9]{4,6})"))System.out.println("Number not in length range or different format");
Periksa Memvariasikan angka desimal Panjang antara (Asumsikan 4 hingga 7 panjang)
// It will not count the '.' (Period) in lengthString decimal ="132.45";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");String decimal ="1.12";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");String decimal ="1234";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");String decimal ="-10.123";if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Numbers Identified between 4 to 7");String decimal ="123..4";if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Decimal not in range or different format");String decimal ="132";if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Decimal not in range or different format");String decimal ="1.1";if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))System.out.println("Decimal not in range or different format");
Didasarkan atas jawaban lain saya menulis sendiri dan tidak menggunakan pola atau parsing dengan pengecekan pengecualian.
Ia memeriksa maksimum satu tanda minus dan memeriksa maksimum satu titik desimal.
Berikut ini beberapa contoh dan hasilnya:
"1", "-1", "-1.5" dan "-1.556" mengembalikan true
"1..5", "1A.5", "1.5D", "-" dan "--1" menghasilkan false
Catatan: Jika perlu, Anda dapat memodifikasi ini untuk menerima parameter Lokal dan meneruskannya ke panggilan DecimalFormatSymbols.getInstance () untuk menggunakan Lokal tertentu alih-alih yang sekarang.
publicstaticboolean isNumeric(finalString input){//Check for null or blank stringif(input ==null|| input.isBlank())returnfalse;//Retrieve the minus sign and decimal separator characters from the current Localefinal var localeMinusSign =DecimalFormatSymbols.getInstance().getMinusSign();final var localeDecimalSeparator =DecimalFormatSymbols.getInstance().getDecimalSeparator();//Check if first character is a minus signfinal var isNegative = input.charAt(0)== localeMinusSign;//Check if string is not just a minus signif(isNegative && input.length()==1)returnfalse;
var isDecimalSeparatorFound =false;//If the string has a minus sign ignore the first characterfinal var startCharIndex = isNegative ?1:0;//Check if each character is a number or a decimal separator//and make sure string only has a maximum of one decimal separatorfor(var i = startCharIndex; i < input.length(); i++){if(!Character.isDigit(input.charAt(i))){if(input.charAt(i)== localeDecimalSeparator &&!isDecimalSeparatorFound){
isDecimalSeparatorFound =true;}elsereturnfalse;}}returntrue;}
Berikut adalah dua metode yang mungkin berhasil. (Tanpa menggunakan Pengecualian). Catatan: Java adalah nilai pass-by-nilai secara default dan nilai String adalah alamat data objek String. Jadi, ketika Anda melakukannya
stringNumber = stringNumber.replaceAll(" ","");
Anda telah mengubah nilai input menjadi tidak ada spasi. Anda dapat menghapus garis itu jika mau.
Berikut adalah metode lain jika Anda ingin mengizinkan pelampung. Metode ini diduga memungkinkan angka-angka dalam bentuk lulus 1.123,123,123,123,123,123.123 saya baru saja membuatnya, dan saya pikir perlu pengujian lebih lanjut untuk memastikannya berfungsi.
privateboolean isValidStringTrueNumber(String stringNumber){if(stringNumber.isEmpty()){returnfalse;}
stringNumber = stringNumber.replaceAll(" ","");int countOfDecimalPoint =0;boolean decimalPointPassed =false;boolean commaFound =false;int countOfDigitsBeforeDecimalPoint =0;int countOfDigitsAfterDecimalPoint =0;int commaCounter=0;int countOfDigitsBeforeFirstComma =0;char[] charNumber = stringNumber.toCharArray();for(int i =0; i<charNumber.length ;i++){if((commaCounter>3)||(commaCounter<0)){returnfalse;}if(!Character.isDigit(charNumber[i]))//Char is not a digit.{if(charNumber[i]==','){if(decimalPointPassed){returnfalse;}
commaFound =true;//check that next three chars are only digits.
commaCounter +=3;}elseif(charNumber[i]=='.'){
decimalPointPassed =true;
countOfDecimalPoint++;}else{returnfalse;}}else//Char is a digit.{if((commaCounter>=0)&&(commaFound)){if(!decimalPointPassed){
commaCounter--;}}if(!commaFound){
countOfDigitsBeforeFirstComma++;}if(!decimalPointPassed){
countOfDigitsBeforeDecimalPoint++;}else{
countOfDigitsAfterDecimalPoint++;}}}if((commaFound)&&(countOfDigitsBeforeFirstComma>3)){returnfalse;}if(countOfDecimalPoint>1){returnfalse;}if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0))){returnfalse;}returntrue;}
Oh, pertanyaan bagus. Saya kira ini hanya bekerja bilangan bulat tipe normal. Metode awalnya dibuat untuk menyaring input nomor telepon, dan menghitung angka.
Integer.parseInt()
akan gagal menguraikan nomor ponselNumberFormatException
.Jawaban:
Dengan Apache Commons Lang 3.5 dan lebih tinggi:
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
string kosong dan mengabaikan spasi internal dalam string. Cara lain adalah dengan menggunakanNumberUtils.isParsable
yang pada dasarnya memeriksa nomor yang dapat diuraikan menurut Java. (The javadocs yang ditautkan berisi contoh terperinci untuk setiap metode.)sumber
StringUtils.isNumeric()
mungkin tidak akan sesuai di sini karena hanya memeriksa apakah string adalah urutan digit. Akan baik untuk sebagian besar int tetapi tidak demikian untuk angka dengan desimal, pemisah grup, dll.StringUtils
tidak mendukung tanda-tanda terkemuka tetapi Anda harus memeriksaNumberUtils.isCreatable
, ini mendukung negatif dengan benar.Ini umumnya dilakukan dengan fungsi sederhana yang ditentukan pengguna (yaitu fungsi Roll-your-own "isNumeric").
Sesuatu seperti:
Namun, jika Anda sering memanggil fungsi ini, dan Anda berharap banyak cek gagal karena tidak menjadi angka maka kinerja mekanisme ini tidak akan bagus, karena Anda mengandalkan pengecualian yang dilemparkan untuk setiap kegagalan, yang merupakan operasi yang cukup mahal.
Pendekatan alternatif mungkin menggunakan ekspresi reguler untuk memeriksa validitas menjadi nomor:
Berhati-hatilah dengan mekanisme RegEx di atas, karena akan gagal jika Anda menggunakan angka non-Arab (yaitu angka selain 0 hingga 9). Ini karena bagian "\ d" dari RegEx hanya akan cocok dengan [0-9] dan secara efektif tidak sadar secara numerik secara internasional. (Terima kasih kepada OregonGhost untuk menunjukkan ini!)
Atau bahkan alternatif lain adalah dengan menggunakan Java.text.NumberFormat objek bawaan Java untuk melihat apakah, setelah mengurai string posisi parser berada di akhir string. Jika ya, kita dapat menganggap seluruh string adalah numerik:
sumber
.
dalam regex Anda akan cocok dengan karakter apa pun, bukan hanya karakter pemisah desimal.Jika Anda menggunakan Android, maka Anda harus menggunakan:
dokumentasi dapat ditemukan di sini
tetap sederhana . kebanyakan orang dapat "memprogram ulang" (hal yang sama).
sumber
.
,-
Ekspresi lambda Java 8
sumber
Seperti @CraigTP telah menyebutkan dalam jawaban yang sangat baik, saya juga memiliki masalah kinerja yang serupa dalam menggunakan Pengecualian untuk menguji apakah string tersebut numerik atau tidak. Jadi saya akhirnya memisahkan string dan menggunakan
java.lang.Character.isDigit()
.Menurut Javadoc ,
Character.isDigit(char)
akan dengan benar mengenali angka non-Latin. Dari segi kinerja, saya pikir perbandingan N sederhana di mana N adalah jumlah karakter dalam string akan lebih efisien secara komputasi daripada melakukan pencocokan regex.UPDATE: Seperti yang ditunjukkan oleh Jean-François Corbett dalam komentar, kode di atas hanya akan memvalidasi bilangan bulat positif, yang mencakup sebagian besar kasus penggunaan saya. Di bawah ini adalah kode yang diperbarui yang memvalidasi angka desimal dengan benar sesuai dengan lokal default yang digunakan dalam sistem Anda, dengan asumsi bahwa pemisah desimal hanya terjadi satu kali dalam string.
sumber
toCharArray()
akan membuat salinan array di objek String karena String tidak berubah. Mungkin lebih cepat menggunakancharAt(int index)
metode pada objek String secara langsung.StringIndexOutOfBoundsException
ketika melewati string dengan panjang 0. Dapat diperbaiki denganif(str.length() == 0) return false;
Perpustakaan Guava Google menyediakan metode pembantu yang baik untuk melakukan hal ini:
Ints.tryParse
. Anda menggunakannya sepertiInteger.parseInt
tetapi mengembalikannull
daripada melemparkan Pengecualian jika string tidak mem-parsing ke integer yang valid. Perhatikan bahwa ia mengembalikan Integer, bukan int, jadi Anda harus mengonversi / autobox kembali ke int.Contoh:
Namun, pada rilis saat ini - Jambu r11 - masih ditandai @Beta.
Saya belum membandingkannya. Melihat kode sumber ada beberapa overhead dari banyak pemeriksaan kewarasan tetapi pada akhirnya mereka menggunakan
Character.digit(string.charAt(idx))
, mirip, tetapi sedikit berbeda dari, jawaban dari @Ibrahim di atas. Tidak ada pengecualian menangani overhead di bawah penutup dalam implementasinya.sumber
Jangan gunakan Pengecualian untuk memvalidasi nilai Anda. Gunakan Util libs sebagai gantinya seperti apache NumberUtils:
Edit :
Harap perhatikan bahwa, jika string Anda dimulai dengan 0, NumberUtils akan menafsirkan nilai Anda sebagai heksadesimal.
sumber
Number.isNumber()
.Number.isNumber()
hadir dari versi pertama jawaban, tertanggal 24 Sep 12 pada 17:01.Mengapa semua orang mendorong solusi pengecualian / regex?
Walaupun saya bisa mengerti kebanyakan orang baik-baik saja dengan menggunakan try / catch, jika Anda ingin sering melakukannya ... itu bisa sangat melelahkan.
Apa yang saya lakukan di sini adalah mengambil regex, metode parseNumber (), dan metode pencarian array untuk melihat mana yang paling efisien. Kali ini, saya hanya melihat angka integer.
Hasil dalam kecepatan yang saya dapatkan adalah:
Penafian: Saya tidak mengklaim metode ini 100% dioptimalkan, mereka hanya untuk demonstrasi data
Pengecualian dimenangkan jika dan hanya jika jumlahnya 4 karakter atau kurang, dan setiap string selalu angka ... dalam hal ini, mengapa bahkan memiliki cek?
Singkatnya, sangat menyakitkan jika Anda sering menemukan nomor yang tidak valid dengan try / catch, yang masuk akal. Aturan penting yang selalu saya ikuti adalah JANGAN PERNAH menggunakan try / catch untuk aliran program . Ini adalah contoh mengapa.
Menariknya, simpel jika char <0 || > 9 sangat sederhana untuk ditulis, mudah diingat (dan harus bekerja dalam berbagai bahasa) dan memenangkan hampir semua skenario pengujian.
Satu-satunya downside adalah bahwa saya menebak Integer.parseInt () mungkin menangani angka non ASCII, sedangkan metode pencarian array tidak.
Bagi mereka yang bertanya-tanya mengapa saya mengatakan mudah untuk mengingat satu array karakter, jika Anda tahu tidak ada tanda-tanda negatif, Anda dapat dengan mudah lolos dengan sesuatu yang kental seperti ini:
Terakhir sebagai catatan terakhir, saya ingin tahu tentang operator asistensi dalam contoh yang diterima dengan semua suara di atas. Menambahkan penugasan
tidak hanya tidak berguna karena Anda bahkan tidak menggunakan nilai, tetapi juga membuang-buang waktu pemrosesan dan meningkatkan runtime oleh beberapa nanodetik (yang menyebabkan peningkatan 100-200 ms dalam tes). Saya tidak dapat melihat mengapa ada orang yang melakukan itu karena ini adalah pekerjaan tambahan untuk mengurangi kinerja.
Anda akan berpikir bahwa itu akan dioptimalkan ... meskipun mungkin saya harus memeriksa bytecode dan melihat apa yang dilakukan oleh kompiler. Itu tidak menjelaskan mengapa itu selalu tampak lebih panjang bagi saya meskipun jika entah bagaimana dioptimalkan keluar ... karena itu saya bertanya-tanya apa yang terjadi. Sebagai catatan: Secara lebih panjang, maksud saya menjalankan tes untuk 10.000.000 iterasi, dan menjalankan program itu beberapa kali (10x +) selalu menunjukkan itu lebih lambat.
EDIT: Diperbarui tes untuk Character.isDigit ()
sumber
Ekspresi reguler CraigTP (ditampilkan di atas) menghasilkan beberapa positif palsu. Misalnya "23y4" akan dihitung sebagai angka karena '.' cocok dengan karakter apa pun bukan titik desimal.
Juga akan menolak nomor apa pun dengan '+' yang memimpin
Alternatif yang menghindari dua masalah kecil ini adalah
sumber
true
untuk plus"+"
atau minus tunggal"-"
, danfalse
untuk"0."
"0."
valid untukDouble.parseDouble()
dan merupakan literal yang sah menurut JLS ( §3.10.2 )!matches("-?\\d+([.]\\d+)?")
Kita dapat mencoba mengganti semua angka dari string yang diberikan dengan ("") yaitu ruang kosong dan jika setelah itu panjang string adalah nol maka kita dapat mengatakan bahwa string yang diberikan hanya berisi angka. [Jika Anda menemukan jawaban ini bermanfaat maka silakan pertimbangkan untuk memilihnya] Contoh:
sumber
""
adalah angka tetapi"3.14"
dan"-1"
tidak?Anda bisa menggunakan
NumberFormat#parse
:sumber
value
.Jika Anda menggunakan java untuk mengembangkan aplikasi Android, Anda bisa menggunakan fungsi TextUtils.isDigitsOnly .
sumber
Inilah jawaban saya untuk masalah tersebut.
Sebuah menangkap semua metode kenyamanan yang dapat Anda gunakan untuk mengurai setiap String dengan semua jenis parser:
isParsable(Object parser, String str)
. Parser dapat berupa aClass
atau aobject
. Ini juga akan memungkinkan Anda untuk menggunakan parser khusus yang Anda tulis dan harus berfungsi untuk skenario sebelumnya, misalnya:Ini kode saya lengkap dengan deskripsi metode.
sumber
Untuk mencocokkan hanya bilangan bulat basis-sepuluh positif, yang hanya berisi digit ASCII, gunakan:
sumber
Pendekatan yang berperforma baik menghindari try-catch dan menangani angka negatif dan notasi ilmiah.
sumber
Ini kelas saya untuk memeriksa apakah sebuah string adalah angka. Itu juga memperbaiki string numerik:
Fitur:
Ini dia ...
sumber
Berikut adalah contoh lain pemutakhiran regex "CraigTP" yang ditingkatkan dengan lebih banyak validasi.
sumber
Pengecualian itu mahal, tetapi dalam hal ini RegEx membutuhkan waktu lebih lama. Kode di bawah ini menunjukkan tes sederhana dari dua fungsi - satu menggunakan pengecualian dan satu menggunakan regex. Di komputer saya, versi RegEx 10 kali lebih lambat dari pengecualian.
sumber
// silakan periksa kode di bawah ini
sumber
sumber
Ini contoh sederhana untuk pemeriksaan ini:
sumber
Anda dapat menggunakan objek java.util.Scanner.
sumber
Saya memodifikasi solusi CraigTP untuk menerima notasi ilmiah dan juga titik dan koma sebagai pemisah desimal
contoh
sumber
Itu sebabnya saya menyukai pendekatan Try * di .NET. Selain metode Parse tradisional yang seperti Java, Anda juga memiliki metode TryParse. Saya tidak pandai sintaksis Java (parameter out?), Jadi tolong perlakukan yang berikut ini sebagai semacam pseudo-code. Seharusnya konsepnya jelas.
Pemakaian:
sumber
Parse itu (yaitu dengan
Integer#parseInt
) dan cukup menangkap pengecualian. =)Untuk memperjelas: Fungsi parseInt memeriksa apakah ia dapat menguraikan nomor dalam kasus apa pun (jelas) dan jika Anda tetap ingin menguraikannya, Anda tidak akan mendapatkan kinerja yang terpukul dengan benar-benar melakukan parsing.
Jika Anda tidak ingin menguraikannya (atau menguraikannya sangat, sangat jarang), Anda tentu ingin melakukannya secara berbeda.
sumber
Anda dapat menggunakan NumberUtils.isCreatable () dari Apache Commons Lang .
Karena NumberUtils.isNumber akan ditinggalkan pada 4.0, jadi gunakan NumberUtils.isCreatable () sebagai gantinya.
sumber
Java 8 Stream, ekspresi lambda, antarmuka fungsional
Semua kasus ditangani ( string null, string kosong dll )
sumber
Saya telah menggambarkan beberapa kondisi untuk memeriksa angka dan desimal tanpa menggunakan API apa pun,
Periksa Perbaiki Panjang 1 digit angka
Periksa nomor Fix Length (Asumsikan panjang 6)
Periksa nomor Panjang yang Bervariasi antara (Asumsikan panjang 4 hingga 6)
Periksa Memvariasikan angka desimal Panjang antara (Asumsikan 4 hingga 7 panjang)
Semoga ini bisa membantu orang lain.
sumber
Didasarkan atas jawaban lain saya menulis sendiri dan tidak menggunakan pola atau parsing dengan pengecekan pengecualian.
Ia memeriksa maksimum satu tanda minus dan memeriksa maksimum satu titik desimal.
Berikut ini beberapa contoh dan hasilnya:
"1", "-1", "-1.5" dan "-1.556" mengembalikan true
"1..5", "1A.5", "1.5D", "-" dan "--1" menghasilkan false
Catatan: Jika perlu, Anda dapat memodifikasi ini untuk menerima parameter Lokal dan meneruskannya ke panggilan DecimalFormatSymbols.getInstance () untuk menggunakan Lokal tertentu alih-alih yang sekarang.
sumber
Berikut adalah dua metode yang mungkin berhasil. (Tanpa menggunakan Pengecualian). Catatan: Java adalah nilai pass-by-nilai secara default dan nilai String adalah alamat data objek String. Jadi, ketika Anda melakukannya
Anda telah mengubah nilai input menjadi tidak ada spasi. Anda dapat menghapus garis itu jika mau.
Berikut adalah metode lain jika Anda ingin mengizinkan pelampung. Metode ini diduga memungkinkan angka-angka dalam bentuk lulus 1.123,123,123,123,123,123.123 saya baru saja membuatnya, dan saya pikir perlu pengujian lebih lanjut untuk memastikannya berfungsi.
sumber