在解析字符串之前,如何检查它是否是一个数字?
当前回答
这是我知道的最快的方法来检查字符串是否为数字:
public static boolean isNumber(String str){
int i=0, len=str.length();
boolean a=false,b=false,c=false, d=false;
if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-')) i++;
while( i<len && isDigit(str.charAt(i)) ){ i++; a=true; }
if(i<len && (str.charAt(i)=='.')) i++;
while( i<len && isDigit(str.charAt(i)) ){ i++; b=true; }
if(i<len && (str.charAt(i)=='e' || str.charAt(i)=='E') && (a || b)){ i++; c=true; }
if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-') && c) i++;
while( i<len && isDigit(str.charAt(i)) ){ i++; d=true;}
return i==len && (a||b) && (!c || (c && d));
}
static boolean isDigit(char c){
return c>='0' && c<='9';
}
其他回答
一个有效的方法避免尝试捕获和处理负数和科学符号。
Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );
public static boolean isNumeric( String value )
{
return value != null && PATTERN.matcher( value ).matches();
}
// only int
public static boolean isNumber(int num)
{
return (num >= 48 && c <= 57); // 0 - 9
}
// is type of number including . - e E
public static boolean 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
public static boolean 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;
}
public static boolean isNumeric(String s)
{
try
{
Double.parseDouble(s);
return true;
}
catch (Exception e)
{
return false;
}
}
import java.util.Scanner;
public class TestDemo {
public static void main(String[] args) {
boolean flag = true;
Scanner sc = new Scanner(System.in);
System.out.println("Enter the String:");
String str = sc.nextLine();
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i) > 48 && str.charAt(i) < 58) {
flag = false;
break;
}
}
if(flag == true) {
System.out.println("String is a valid String.");
} else {
System.out.println("String contains number.");
}
}
}
异常开销很大,但在这种情况下,RegEx需要更长的时间。下面的代码显示了两个函数的简单测试——一个使用异常,一个使用正则表达式。在我的机器上,RegEx版本比异常慢10倍。
import java.util.Date;
public class IsNumeric {
public static boolean isNumericOne(String s) {
return s.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isNumericTwo(String s) {
try {
Double.parseDouble(s);
return true;
} catch (Exception e) {
return false;
}
}
public static void main(String [] args) {
String test = "12345.F";
long before = new Date().getTime();
for(int x=0;x<1000000;++x) {
//isNumericTwo(test);
isNumericOne(test);
}
long after = new Date().getTime();
System.out.println(after-before);
}
}
谷歌的Guava库提供了一个很好的辅助方法:你可以像使用Integer一样使用它。parseInt,但如果字符串没有解析为有效整数,它将返回null而不是抛出异常。注意,它返回的是Integer,而不是int,所以你必须将它转换/自动装箱回int。
例子:
String s1 = "22";
String s2 = "22.2";
Integer oInt1 = Ints.tryParse(s1);
Integer oInt2 = Ints.tryParse(s2);
int i1 = -1;
if (oInt1 != null) {
i1 = oInt1.intValue();
}
int i2 = -1;
if (oInt2 != null) {
i2 = oInt2.intValue();
}
System.out.println(i1); // prints 22
System.out.println(i2); // prints -1
但是,在当前发行版(Guava r11)中,它仍然被标记为@Beta。
我还没有对它进行基准测试。查看源代码,有一些开销来自大量的完整性检查,但最终他们使用Character.digit(string.charAt(idx)),类似,但略有不同,从@Ibrahim上面的答案。在它们的实现中没有异常处理开销。
推荐文章
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- 我如何检查如果一个变量是JavaScript字符串?
- 如何显示有两个小数点后的浮点数?
- Java生成两个给定值之间的随机数
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 比较JUnit断言中的数组,简洁的内置方式?
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 在Lua中拆分字符串?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?