public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
这只是我一个人吗,或者这看起来有点黑吗?有什么更好的方法?
查看我的答案(带有基准,基于先前CodingWithSpike的答案),以了解为什么我改变了立场并接受了乔纳斯·克林明(Jonas Klemming)对这个问题的答案。我认为大多数人会使用此原始代码,因为它实现起来更快,更易于维护,但是在提供非整数数据时,它的速度要慢几个数量级。
#1 楼
如果您不担心潜在的溢出问题,则此功能的执行速度将比使用Integer.parseInt()
快20-30倍。public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
评论
(c <='/'|| c> =':')看起来有点奇怪。我本来会用(c <'0'|| c>'9')...在Java中<=和> =运算符是否更快?
–匿名
08-10-26在1:43
为什么不使用正则表达式?返回的str.matches(“ ^-?\\ d + $”)是否与上面的代码相同。
– Maglob
08-10-26在9:28
我会使用此方法或正则表达式之前的问题中的原始方法。这是性能,是实现速度和纯粹的可维护性的原始方法。正则表达式解决方案无济于事。
–比尔蜥蜴
08-10-26在13:19
我担心溢出,但是此方法可以适用于BigInts,并且仍然比其他方法更快。如果有人想知道为什么我要花这么大的精力解决这个简单的问题,我会创建一个库来帮助解决Euler项目的问题。
–比尔蜥蜴
08-10-26在13:25
如果您担心是否可以将字符串实际解析为int或long类型,则还需要检查字符串表示的整数是否真正适合这些数据类型。
–乔纳斯·K(Jonas K)
2014年9月29日在9:48
#2 楼
您已经拥有了,但是只应该抓住NumberFormatException
。评论
是的,捕获比您需要更多的异常被认为是不好的形式。
–克里斯
08-10-26在1:28
你是对的。 NFE是唯一可以抛出的错误,但要养成这种习惯仍然不好。
–比尔蜥蜴
08-10-26在3:26
我认为如果输入为null,则可以引发NPE,因此您的方法可能应该显式地处理该NPE,无论您采用哪种方式。
– Dov Wasserman
08-10-26在8:07
@Dov:您是对的,应该同时明确捕获NPE和NFE。
–比尔蜥蜴
08-10-26在12:35
这个回答应该是对这个问题的真正答案。
–
2012-2-10的3:51
#3 楼
做一个快速基准测试。异常实际上并不昂贵,除非您开始弹出多个方法,并且JVM必须做大量工作才能使执行堆栈就位。当使用相同的方法时,它们的性能并不差。 public void RunTests()
{
String str = "1234567890";
long startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByException(str);
long endTime = System.currentTimeMillis();
System.out.print("ByException: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByRegex(str);
endTime = System.currentTimeMillis();
System.out.print("ByRegex: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByJonas(str);
endTime = System.currentTimeMillis();
System.out.print("ByJonas: ");
System.out.println(endTime - startTime);
}
private boolean IsInt_ByException(String str)
{
try
{
Integer.parseInt(str);
return true;
}
catch(NumberFormatException nfe)
{
return false;
}
}
private boolean IsInt_ByRegex(String str)
{
return str.matches("^-?\d+$");
}
public boolean IsInt_ByJonas(String str)
{
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c <= '/' || c >= ':') {
return false;
}
}
return true;
}
输出:
ByException:31
ByRegex:453(注意:每次都要重新编译模式)
ByJonas:16
我同意乔纳斯·K的解决方案也是最强大的看起来他赢了:)
评论
对这三个进行基准测试的好主意。公平地对待Regex和Jonas方法,应该使用非整数字符串进行测试,因为这是Integer.parseInt方法将真正放慢速度的地方。
–比尔蜥蜴
08-10-26在13:00
抱歉,此正则表达式测试不好。 (1)您不需要第二次检查^和$,因为在匹配中整个字符串必须与regex匹配,(2)每次str.matches都必须创建自己的Pattern,这很昂贵。出于性能原因,我们只应在此方法外部创建一次这样的Pattern,然后在内部使用它。 (3)我们也只能创建一个Matcher对象,并使用其reset(CharSequence)传递用户数据并返回其match()结果。
– Pshemo
2013年11月6日15:01
所以像私有的最终匹配器m = Pattern.compile(“-?\\ d +”)。matcher(“”);私有布尔值byRegex(String str){return m.reset(str).matches(); }应该有更好的性能。
– Pshemo
2013年11月6日15:02
@Pshemo Integer.valueOf(“ 1”)和Integer.valueOf(“ 1”)都抛出异常,因此检查^和$似乎很合理。
–cquezel
15年5月12日在17:33
@cquezel是的,但不是必需的,因为匹配项将隐式添加^和$。看一下“ 123” .matches(“ \\ d +”)和“ 123” .matches(“ \\ d +”)的结果。您将看到错误和真实。将返回false,因为字符串以空格开头,从而使正则表达式无法完全匹配它。
– Pshemo
15年5月12日在18:07
#4 楼
由于有可能人们仍然会来这里访问,并且在基准测试之后会对Regex持偏见...所以我要提供基准测试的更新版本和Regex的编译版本。与以前的基准测试相反,此示例显示Regex解决方案实际上一直具有良好的性能。从蜥蜴人比尔(Bill the Lizard)复制并更新为已编译版本:
private final Pattern pattern = Pattern.compile("^-?\d+$");
public void runTests() {
String big_int = "1234567890";
String non_int = "1234XY7890";
long startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByException(big_int);
long endTime = System.currentTimeMillis();
System.out.print("ByException - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByException(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByException - non-integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByRegex(big_int);
endTime = System.currentTimeMillis();
System.out.print("\nByRegex - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByRegex(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByRegex - non-integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
IsInt_ByCompiledRegex(big_int);
endTime = System.currentTimeMillis();
System.out.print("\nByCompiledRegex - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
IsInt_ByCompiledRegex(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByCompiledRegex - non-integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByJonas(big_int);
endTime = System.currentTimeMillis();
System.out.print("\nByJonas - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByJonas(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByJonas - non-integer data: ");
System.out.println(endTime - startTime);
}
private boolean IsInt_ByException(String str)
{
try
{
Integer.parseInt(str);
return true;
}
catch(NumberFormatException nfe)
{
return false;
}
}
private boolean IsInt_ByRegex(String str)
{
return str.matches("^-?\d+$");
}
private boolean IsInt_ByCompiledRegex(String str) {
return pattern.matcher(str).find();
}
public boolean IsInt_ByJonas(String str)
{
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c <= '/' || c >= ':') {
return false;
}
}
return true;
}
结果:
ByException - integer data: 45
ByException - non-integer data: 465
ByRegex - integer data: 272
ByRegex - non-integer data: 131
ByCompiledRegex - integer data: 45
ByCompiledRegex - non-integer data: 26
ByJonas - integer data: 8
ByJonas - non-integer data: 2
评论
ByCompiledRegex时间需要在其时间度量中包括编译正则表达式。
–马丁·卡尼(Martin Carney)
2013年12月23日20:53
@MartinCarney我对其进行了修改并对模式编译进行了基准测试。显然,我的CPU / JIT速度更快,但是如果将其内插,则编译时间为336。
–tedder42
2014年10月8日23:26
需要明确的是,当模式编译完成10万次时,与所有其他行一样,发生336(ms)。暗示它只做一次,它的时间基本上为零。
–tedder42
2014年10月8日23:50
感谢您直接在已编译的正则表达式时间设置记录。
– LarsH
16-11-30在6:50
也许“ ^ [+-]?\\ d + $”会更好。
–亚当
17年5月15日在10:54
#5 楼
org.apache.commons.lang.StringUtils.isNumeric
尽管Java的标准库确实错过了这些实用程序功能
我认为Apache Commons是每个Java程序员的“必不可少的”
不好,它还没有移植到Java5
评论
唯一的问题是溢出:S我仍然给您+1提到commons-lang :)
–javamonkey79
10年7月27日在23:55
另一个问题是负数,但我也+1,因为我认为这种方法最接近一种好的解决方案。
–桑德里斯
13年1月9日在7:38
#6 楼
这部分取决于您所说的“可以转换为整数”的意思。如果您的意思是“可以用Java转换为int”,那么Jonas的答案是一个很好的开始,但没有尚未完全完成工作。例如,它将通过9999999999999999999999999999999999。我会在方法末尾添加来自您自己问题的普通try / catch调用。
逐字符检查将有效地拒绝“根本不是整数”的情况,而将“一个整数,但Java无法处理它”的情况将被较慢的异常路由捕获。您也可以手动完成此操作,但这会复杂得多。
#7 楼
关于正则表达式的一则评论。这里提供的每个示例都是错误的!如果要使用regexp,请不要忘记编译模式会花费很多时间。这:str.matches("^-?\d+$")
还有这个:
Pattern.matches("-?\d+", input);
导致在每个方法调用中编译模式。要正确使用它,请遵循:
import java.util.regex.Pattern;
/**
* @author Rastislav Komara
*/
public class NaturalNumberChecker {
public static final Pattern PATTERN = Pattern.compile("^\d+$");
boolean isNaturalNumber(CharSequence input) {
return input != null && PATTERN.matcher(input).matches();
}
}
评论
您也可以提前创建Matcher,并使用其reset()方法将其应用于输入,从而提高性能。
–艾伦·摩尔
08-10-27在5:43
#8 楼
有番石榴版本:import com.google.common.primitives.Ints;
Integer intValue = Ints.tryParse(stringValue);
如果解析字符串失败,它将返回null而不是引发异常。
评论
最佳答案恕我直言。使用经过良好测试的库,而不要汇总自己的解决方案。 (另请参见此处的讨论。)
–奥利维尔·卡柳克斯(Olivier Cailloux)
17年8月25日在11:47
#9 楼
我从rally25rs答案中复制了代码,并为非整数数据添加了一些测试。结果无可否认地支持Jonas Klemming发表的方法。当您拥有整数数据时,我最初发布的Exception方法的结果非常好,但是当您没有整数数据时,结果最差,而RegEx解决方案的结果(我敢打赌,很多人会使用)一直很糟糕。请参阅Felipe的答案,以获得编译的正则表达式示例,该示例要快得多。public void runTests()
{
String big_int = "1234567890";
String non_int = "1234XY7890";
long startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByException(big_int);
long endTime = System.currentTimeMillis();
System.out.print("ByException - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByException(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByException - non-integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByRegex(big_int);
endTime = System.currentTimeMillis();
System.out.print("\nByRegex - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByRegex(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByRegex - non-integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByJonas(big_int);
endTime = System.currentTimeMillis();
System.out.print("\nByJonas - integer data: ");
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++)
IsInt_ByJonas(non_int);
endTime = System.currentTimeMillis();
System.out.print("ByJonas - non-integer data: ");
System.out.println(endTime - startTime);
}
private boolean IsInt_ByException(String str)
{
try
{
Integer.parseInt(str);
return true;
}
catch(NumberFormatException nfe)
{
return false;
}
}
private boolean IsInt_ByRegex(String str)
{
return str.matches("^-?\d+$");
}
public boolean IsInt_ByJonas(String str)
{
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c <= '/' || c >= ':') {
return false;
}
}
return true;
}
结果:
ByException - integer data: 47
ByException - non-integer data: 547
ByRegex - integer data: 390
ByRegex - non-integer data: 313
ByJonas - integer data: 0
ByJonas - non-integer data: 16
#10 楼
它更短,但是更短不一定更好(并且不会捕获超出范围的整数值,如danatel的注释中所指出的那样):input.matches("^-?\d+$");
个人而言,由于实现是通过辅助方法来完成的,并且正确性胜过长度,所以我会选择类似您所拥有的东西(减去捕获基本
Exception
类而不是NumberFormatException
)。评论
也许\\ d {1,10}尽管不完美,但在捕获Java整数方面比\\ d +好
– Maglob
08-10-25在23:15
#11 楼
您可以使用字符串类的matchs方法。 [0-9]表示它可以为所有值,+表示必须至少一个字符长,*表示可以为零个或多个字符。boolean isNumeric = yourString.matches("[0-9]+"); // 1 or more characters long, numbers only
boolean isNumeric = yourString.matches("[0-9]*"); // 0 or more characters long, numbers only
评论
Nb,它与“ +10”或“ -10”不匹配),通常将其作为有效整数包含在内
– Tim Wintle
15年4月27日在15:05
#12 楼
怎么样:return Pattern.matches("-?\d+", input);
评论
整数9999999999999999999999999999999999怎么样?
– danatel
08-10-25在23:06
不要忘记检查负号。
–杰里米·鲁滕(Jeremy Ruten)
08-10-25在23:06
您是否不需要锚定正则表达式的开头和结尾,以免传递“ aaa-1999zzz”?
–蒂姆·霍兰德
08-10-26在13:08
蒂姆,当您调用matches()方法之一(字符串,模式和匹配器各有一个)时,正则表达式必须匹配整个输入,从而使锚点变得多余。要找到大多数其他正则表达式风格定义的匹配项,必须使用Matcher#find()。
–艾伦·摩尔
08-10-27在5:23
#13 楼
这是Jonas Klemming的Java 8变体答案:public static boolean isInteger(String str) {
return str != null && str.length() > 0 &&
IntStream.range(0, str.length()).allMatch(i -> i == 0 && (str.charAt(i) == '-' || str.charAt(i) == '+')
|| Character.isDigit(str.charAt(i)));
}
测试代码:
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
Arrays.asList("1231231", "-1232312312", "+12313123131", "qwqe123123211", "2", "0000000001111", "", "123-", "++123",
"123-23", null, "+-123").forEach(s -> {
System.out.printf("%15s %s%n", s, isInteger(s));
});
}
测试代码:
1231231 true
-1232312312 true
+12313123131 true
qwqe123123211 false
2 true
0000000001111 true
false
123- false
++123 false
123-23 false
null false
+-123 false
#14 楼
您只需检查NumberFormatException:- String value="123";
try
{
int s=Integer.parseInt(any_int_val);
// do something when integer values comes
}
catch(NumberFormatException nfe)
{
// do something when string values comes
}
#15 楼
如果您的String数组包含纯Integer和String,则下面的代码应该可用。您只需要看第一个字符即可。例如[“ 4”,“ 44”,“ abc”,“ 77”,“ bond”]
if (Character.isDigit(string.charAt(0))) {
//Do something with int
}
#16 楼
您还可以使用Scanner类,并使用hasNextInt()-这还允许您测试其他类型,例如浮点数等。评论
这个答案给了我必要的提醒。我完全忘记了Scanner具有这样的功能。 T型
–Hubro
2010-10-26 14:15
#17 楼
如果要检查字符串是否表示适合int类型的整数,我对jonas的答案进行了一些修改,以便表示大于Integer.MAX_VALUE或小于Integer.MIN_VALUE的整数的字符串现在将返回假。例如:“ 3147483647”将返回false,因为3147483647大于2147483647,同样,“-2147483649”也将返回false,因为-2147483649小于-2147483648。public static boolean isInt(String s) {
if(s == null) {
return false;
}
s = s.trim(); //Don't get tricked by whitespaces.
int len = s.length();
if(len == 0) {
return false;
}
//The bottom limit of an int is -2147483648 which is 11 chars long.
//[note that the upper limit (2147483647) is only 10 chars long]
//Thus any string with more than 11 chars, even if represents a valid integer,
//it won't fit in an int.
if(len > 11) {
return false;
}
char c = s.charAt(0);
int i = 0;
//I don't mind the plus sign, so "+13" will return true.
if(c == '-' || c == '+') {
//A single "+" or "-" is not a valid integer.
if(len == 1) {
return false;
}
i = 1;
}
//Check if all chars are digits
for(; i < len; i++) {
c = s.charAt(i);
if(c < '0' || c > '9') {
return false;
}
}
//If we reached this point then we know for sure that the string has at
//most 11 chars and that they're all digits (the first one might be a '+'
// or '-' thought).
//Now we just need to check, for 10 and 11 chars long strings, if the numbers
//represented by the them don't surpass the limits.
c = s.charAt(0);
char l;
String limit;
if(len == 10 && c != '-' && c != '+') {
limit = "2147483647";
//Now we are going to compare each char of the string with the char in
//the limit string that has the same index, so if the string is "ABC" and
//the limit string is "DEF" then we are gonna compare A to D, B to E and so on.
//c is the current string's char and l is the corresponding limit's char
//Note that the loop only continues if c == l. Now imagine that our string
//is "2150000000", 2 == 2 (next), 1 == 1 (next), 5 > 4 as you can see,
//because 5 > 4 we can guarantee that the string will represent a bigger integer.
//Similarly, if our string was "2139999999", when we find out that 3 < 4,
//we can also guarantee that the integer represented will fit in an int.
for(i = 0; i < len; i++) {
c = s.charAt(i);
l = limit.charAt(i);
if(c > l) {
return false;
}
if(c < l) {
return true;
}
}
}
c = s.charAt(0);
if(len == 11) {
//If the first char is neither '+' nor '-' then 11 digits represent a
//bigger integer than 2147483647 (10 digits).
if(c != '+' && c != '-') {
return false;
}
limit = (c == '-') ? "-2147483648" : "+2147483647";
//Here we're applying the same logic that we applied in the previous case
//ignoring the first char.
for(i = 1; i < len; i++) {
c = s.charAt(i);
l = limit.charAt(i);
if(c > l) {
return false;
}
if(c < l) {
return true;
}
}
}
//The string passed all tests, so it must represent a number that fits
//in an int...
return true;
}
评论
您能否编辑您的答案并解释它如何改善您先前提到的答案?
– Gilles Gouaillardet
17年8月25日在2:26
感谢您的出色回答。但是,“ 123”,即123与空格一起被视为有效整数。
– Saikrishna Radarapu
18-4-20在8:37
@SaikrishnaRadarapu他们使用trim()显然是故意的设计选择。
– Guildstern
6月20日22:08
#18 楼
您可以尝试apache utilsNumberUtils.isCreatable(myText)
在此处查看javadoc
评论
似乎在最新版本的链接中不赞成使用此方法。显然,您应该改用isCreateable(String)。
– Guildstern
6月19日11:36
更新。谢谢@Guildenstern
– Borjab
6月19日12:23
#19 楼
您可能还需要考虑用例:如果大多数时候您希望数字有效,那么捕获异常只会在尝试转换无效数字时引起性能开销。调用某些
isInteger()
方法然后使用Integer.parseInt()
进行转换将始终导致有效数字的性能开销-字符串被解析两次,一次由检查,一次由转换。#20 楼
这是Jonas代码的修改形式,该代码检查字符串是否在要转换为整数的范围内。public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
int i = 0;
// set the length and value for highest positive int or lowest negative int
int maxlength = 10;
String maxnum = String.valueOf(Integer.MAX_VALUE);
if (str.charAt(0) == '-') {
maxlength = 11;
i = 1;
maxnum = String.valueOf(Integer.MIN_VALUE);
}
// verify digit length does not exceed int range
if (length > maxlength) {
return false;
}
// verify that all characters are numbers
if (maxlength == 11 && length == 1) {
return false;
}
for (int num = i; num < length; num++) {
char c = str.charAt(num);
if (c < '0' || c > '9') {
return false;
}
}
// verify that number value is within int range
if (length == maxlength) {
for (; i < length; i++) {
if (str.charAt(i) < maxnum.charAt(i)) {
return true;
}
else if (str.charAt(i) > maxnum.charAt(i)) {
return false;
}
}
}
return true;
}
评论
看起来不错,但最后一个for循环需要将i重置为零(如果负数则为1),因为检查每个数字是否为数字的循环将导致i为字符串长度,因此最后一个for循环永远不会运行。我还将使用Java常量Integer.MAX_VALUE和Integer.MIN_VALUE代替魔术数字。
–魔法师蒂姆
2014年8月21日15:42
@TimtheEnchanter谢谢您的建议,我完全忽略了它们。在合并它们的编辑中,我在第一个for循环中使用了一个新变量,以避免多余的if语句。
–韦恩
2014年8月21日在16:47
#21 楼
如果您使用的是Android API,则可以使用:TextUtils.isDigitsOnly(str);
#22 楼
我相信发生异常的风险为零,因为正如您在下面看到的那样,您始终可以安全地将int
解析为String
,而不是相反。因此:
您检查如果您字符串中的每个字符槽都至少匹配
一个字符{“ 0”,“ 1”,“ 2”,“ 3”,“ 4”,“ 5”,“ 6”,“ 7” “,” 8“,” 9“}。
if(aString.substring(j, j+1).equals(String.valueOf(i)))
您总结上述字符在插槽中遇到的所有时间。
>
digits++;
最后,您检查遇到整数的时间是否等于给定字符串的长度。
if(digits == aString.length())
实际上,我们有:
String aString = "1234224245";
int digits = 0;//count how many digits you encountered
for(int j=0;j<aString.length();j++){
for(int i=0;i<=9;i++){
if(aString.substring(j, j+1).equals(String.valueOf(i)))
digits++;
}
}
if(digits == aString.length()){
System.out.println("It's an integer!!");
}
else{
System.out.println("It's not an integer!!");
}
String anotherString = "1234f22a4245";
int anotherDigits = 0;//count how many digits you encountered
for(int j=0;j<anotherString.length();j++){
for(int i=0;i<=9;i++){
if(anotherString.substring(j, j+1).equals(String.valueOf(i)))
anotherDigits++;
}
}
if(anotherDigits == anotherString.length()){
System.out.println("It's an integer!!");
}
else{
System.out.println("It's not an integer!!");
}
结果是:
它是整数!
这不是整数!
同样,您可以验证
String
是float
还是double
,但在这些情况下,您只需遇到一个。字符串中的(点),当然还要检查digits == (aString.length()-1)
再一次,这里遇到解析异常的风险为零,但是如果您打算解析一个已知包含数字的字符串(让我们例如int数据类型),则必须首先检查它是否适合该数据类型。否则,您必须进行投射。
我希望我能提供帮助
#23 楼
另一种选择:private boolean isNumber(String s) {
boolean isNumber = true;
for (char c : s.toCharArray()) {
isNumber = isNumber && Character.isDigit(c);
}
return isNumber;
}
#24 楼
您所做的工作有效,但您可能不应该总是这样检查。应该为“异常”情况保留抛出异常(尽管可能适合您的情况),并且在性能方面非常昂贵。评论
它们只有扔掉才昂贵。
–比尔蜥蜴
08-10-26在12:52
#25 楼
这仅适用于正整数。public static boolean isInt(String str) {
if (str != null && str.length() != 0) {
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) return false;
}
}
return true;
}
评论
欢迎使用stackoverflow。在复活旧线程之前,请确保已阅读之前的答复和评论。实际上已经讨论了这种方法(以及可能的缺点)。
– eigh
2012年3月31日0:20在
#26 楼
这对我有用。只需识别一个字符串是原始数还是数字即可。private boolean isPrimitive(String value){
boolean status=true;
if(value.length()<1)
return false;
for(int i = 0;i<value.length();i++){
char c=value.charAt(i);
if(Character.isDigit(c) || c=='.'){
}else{
status=false;
break;
}
}
return status;
}
#27 楼
要检查所有int字符,您可以简单地使用double负数。if(!searchString.matches(“ [^ 0-9] + $”))...
[^ 0-9] + $检查是否有任何不是整数的字符,因此如果为真,则测试将失败。只是不这样,您就成功了。
评论
不。您显然还没有测试过。仅当字符串中某处有一个数字时,才返回true;否则,如果字符串仅是数字,则不返回。 matchs方法匹配整个字符串,而不只是其中一部分。
–达伍德·伊本·卡里姆(Dawood ibn Kareem)
18年7月22日在20:02
您不会得到双重否定部分。
–罗杰·盖伊
18年7月23日在22:28
好吧,我没有得到双重否定。这根本行不通。如果您混合使用数字和字母,则将其放入if块。不应该这样
–达伍德·伊本·卡里姆(Dawood ibn Kareem)
18年7月23日在23:21
#28 楼
我在这里看到了很多答案,但是大多数答案都可以确定String是否为数字,但是他们无法检查数字是否在Integer范围内...因此,我的目的类似于this:
public static boolean isInteger(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
long value = Long.valueOf(str);
return value >= -2147483648 && value <= 2147483647;
} catch (Exception ex) {
return false;
}
}
评论
好点,由番石榴答案中建议的com.google.common.primitives.Ints.tryParse(String,int)处理。
–艾德里安·贝克(Adrian Baker)
17年1月16日在8:03
但是字符串值也有可能超过长限制。我们怎么能假设它在长距离内。例如,字符串也可以保留此值9,223,372,036,854,775,809,但是长久不能在这种情况下获得NumberFormatException。
–srinivas
19/12/6在3:45
该方法应检查,由String表示的值是否在Integer范围内。如果为该方法提供的参数甚至比Long长,那么它肯定不是整数,并且该方法应返回“ false”。这样做是因为转换会引发错误,然后catch子句将提供“ false”。
–艾洛希尔
19/12/13在15:15
#29 楼
当解释比性能更重要时,我注意到许多讨论都集中在某些解决方案的效率上,但没有一个关于为什么字符串不是整数的讨论。而且,每个人似乎都假定数字“ 2.00”不等于“ 2”。从数学和人类的角度来看,它们是相等的(即使计算机科学说它们不是,并且有充分的理由)。这就是为什么上面的“ Integer.parseInt”解决方案比较弱(取决于您的要求)的原因。无论如何,要使软件更智能,更人性化,我们需要创建具有以下特点的软件:我们这样做并解释了为什么失败了。在这种情况下:
public static boolean isIntegerFromDecimalString(String possibleInteger) {
possibleInteger = possibleInteger.trim();
try {
// Integer parsing works great for "regular" integers like 42 or 13.
int num = Integer.parseInt(possibleInteger);
System.out.println("The possibleInteger="+possibleInteger+" is a pure integer.");
return true;
} catch (NumberFormatException e) {
if (possibleInteger.equals(".")) {
System.out.println("The possibleInteger=" + possibleInteger + " is NOT an integer because it is only a decimal point.");
return false;
} else if (possibleInteger.startsWith(".") && possibleInteger.matches("\.[0-9]*")) {
if (possibleInteger.matches("\.[0]*")) {
System.out.println("The possibleInteger=" + possibleInteger + " is an integer because it starts with a decimal point and afterwards is all zeros.");
return true;
} else {
System.out.println("The possibleInteger=" + possibleInteger + " is NOT an integer because it starts with a decimal point and afterwards is not all zeros.");
return false;
}
} else if (possibleInteger.endsWith(".") && possibleInteger.matches("[0-9]*\.")) {
System.out.println("The possibleInteger="+possibleInteger+" is an impure integer (ends with decimal point).");
return true;
} else if (possibleInteger.contains(".")) {
String[] partsOfPossibleInteger = possibleInteger.split("\.");
if (partsOfPossibleInteger.length == 2) {
//System.out.println("The possibleInteger=" + possibleInteger + " is split into '" + partsOfPossibleInteger[0] + "' and '" + partsOfPossibleInteger[1] + "'.");
if (partsOfPossibleInteger[0].matches("[0-9]*")) {
if (partsOfPossibleInteger[1].matches("[0]*")) {
System.out.println("The possibleInteger="+possibleInteger+" is an impure integer (ends with all zeros after the decimal point).");
return true;
} else if (partsOfPossibleInteger[1].matches("[0-9]*")) {
System.out.println("The possibleInteger=" + possibleInteger + " is NOT an integer because it the numbers after the decimal point (" +
partsOfPossibleInteger[1] + ") are not all zeros.");
return false;
} else {
System.out.println("The possibleInteger=" + possibleInteger + " is NOT an integer because it the 'numbers' after the decimal point (" +
partsOfPossibleInteger[1] + ") are not all numeric digits.");
return false;
}
} else {
System.out.println("The possibleInteger=" + possibleInteger + " is NOT an integer because it the 'number' before the decimal point (" +
partsOfPossibleInteger[0] + ") is not a number.");
return false;
}
} else {
System.out.println("The possibleInteger="+possibleInteger+" is NOT an integer because it has a strange number of decimal-period separated parts (" +
partsOfPossibleInteger.length + ").");
return false;
}
} // else
System.out.println("The possibleInteger='"+possibleInteger+"' is NOT an integer, even though it has no decimal point.");
return false;
}
}
测试代码:
String[] testData = {"0", "0.", "0.0", ".000", "2", "2.", "2.0", "2.0000", "3.14159", ".0001", ".", ".0", "3E24", "6.0221409e+23"};
int i = 0;
for (String possibleInteger : testData ) {
System.out.println("");
System.out.println(i + ". possibleInteger='" + possibleInteger +"' isIntegerFromDecimalString=" + isIntegerFromDecimalString(possibleInteger));
i++;
}
评论
我认为您的解释揭示了人们实际上不会想到的情况,并将允许使用更强大的代码。但是,您假设我们对定界符使用句点(。)。它不包括输入的可读性,例如:千位分隔符,会计括号,其他基数或我们使用阿拉伯数字。也没有理由在此方法中引发异常,因为我们知道该字符串在不可变状态下应处于每种状态,并且我们将成为优秀的程序员并修改引用-进一步阅读wiki.c2.com/?ExceptionPatterns
–大卫·费舍尔
19年11月21日在11:30
大卫-你是绝对正确的;特别是关于逗号分隔符(这对于可读性很重要)。对于真正的通用解决方案,我们需要考虑所有假设-尽管我可以肯定的是,没有太多人使用非阿拉伯数字。 :-)
–蒂哈默(Tihamer)
19年11月22日在14:06
#30 楼
我不喜欢使用正则表达式的方法,因为正则表达式无法检查范围(Integer.MIN_VALUE
,Integer.MAX_VALUE
)。如果您期望在大多数情况下使用int值,而int并不罕见,那么我建议使用
Integer.valueOf
或Integer.parseInt
捕捉到NumberFormatException
。这种方法的优势-您的代码具有良好的可读性:public static boolean isInt(String s) {
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException nfe) {
return false;
}
}
如果您需要检查String是否为整数,并关心性能,那么最好的方法是使用java jdk
Integer.parseInt
的实现,但修改很少(用return false替换抛出):此函数具有良好的性能和保证正确的结果:
public static boolean isInt(String s) {
int radix = 10;
if (s == null) {
return false;
}
if (radix < Character.MIN_RADIX) {
return false;
}
if (radix > Character.MAX_RADIX) {
return false;
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
return false;
if (len == 1) // Cannot have lone "+" or "-"
return false;
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0) {
return false;
}
if (result < multmin) {
return false;
}
result *= radix;
if (result < limit + digit) {
return false;
}
result -= digit;
}
} else {
return false;
}
return true;
}
评论
您对RegExp解决方案有何想法?