java 判断是否整数倍_检查String是否表示Java中的整数的最佳方法是什么?

检查String是否表示Java中的整数的最佳方法是什么?

我通常使用以下习惯来检查String是否可以转换为整数。

public boolean isInteger( String input ) {

try {

Integer.parseInt( input );

return true;

}

catch( Exception e ) {

return false;

}

}

它只是我,还是看起来有点hackish? 什么是更好的方式?

看看我的回答(基于CodingWithSpike的早期答案的基准),看看为什么我改变了我的立场并接受了Jonas Klemming对这个问题的回答。 我认为这个原始代码将被大多数人使用,因为它实现起来更快,更易于维护,但是当提供非整数数据时,它会慢一个数量级。

30个解决方案

149 votes

如果您不关心潜在的溢出问题,此功能的执行速度比使用Integer.parseInt()快20-30倍。

public static boolean isInteger(String str) {

if (str == null) {

return false;

}

if (str.isEmpty()) {

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;

}

Jonas Klemming answered 2019-03-31T21:17:53Z

55 votes

你拥有它,但你应该只抓住NumberFormatException。

Ovidiu Pacurar answered 2019-03-31T21:18:17Z

35 votes

做了一个快速的基准。 除非你开始弹出多个方法并且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

我同意Jonas K的解决方案也是最强大的。 看起来他赢了:)

CodingWithSpike answered 2019-03-31T21:19:09Z

34 votes

因为有可能人们仍然访问这里并且在基准测试后会对Regex产生偏见......所以我将提供一个基准测试的更新版本,以及Regex的编译版本。 与之前的基准测试相反,这一点显示Regex解决方案实际上具有始终如一的良好性能。

从比尔蜥蜴复制并更新编译版本:

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

Felipe answered 2019-03-31T21:19:42Z

27 votes

org.apache.commons.lang.StringUtils.isNumeric

虽然Java的标准库确实错过了这样的实用功能

我认为Apache Commons对每个Java程序员来说都是“必备”

太糟糕了,它还没有移植到Java5

Łukasz Bownik answered 2019-03-31T21:20:24Z

21 votes

它部分取决于你的意思“可以转换为整数”。

如果你的意思是“可以转换为Java中的int”,那么Jonas的答案是一个良好的开端,但还没有完成这项工作。 例如,它将通过99999999999999999999999999999。 我会在方法结束时从你自己的问题中添加正常的try / catch调用。

逐字符检查将有效地拒绝“根本不是一个整数”的情况,留下“它是一个整数,但Java无法处理它”的情况被慢速异常路由捕获。 你也可以手工做到这一点,但它会复杂得多。

Jon Skeet answered 2019-03-31T21:21:02Z

14 votes

关于正则表达式的一个评论。 这里提供的每个例子都是错的! 如果你想使用正则表达式,不要忘记编译模式需要花费很多时间。 这个:

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();

}

}

Rastislav Komara answered 2019-03-31T21:21:39Z

12 votes

我从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

Bill the Lizard answered 2019-03-31T21:22:05Z

7 votes

有番石榴版:

import com.google.common.primitives.Ints;

Integer intValue = Ints.tryParse(stringValue);

如果它无法解析字符串,它将返回null而不是抛出异常。

abalcerek answered 2019-03-31T21:22:35Z

6 votes

这个更短,但更短并不一定更好(并且它不会捕获超出范围的整数值,如danatel的评论中所指出的):

input.matches("^-?\\d+$");

就个人而言,由于实现是以辅助方法进行的,并且正确性超过了长度,我只会选择你所拥有的东西(减去基数Exception而不是NumberFormatException)。

Jonny Buchanan answered 2019-03-31T21:23:07Z

6 votes

您可以使用字符串类的matches方法。 [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

Kaitie answered 2019-03-31T21:23:31Z

3 votes

如果您的String数组包含纯整数和字符串,则下面的代码应该有效。 你只需要看第一个角色。例如[“4”,“44”,“ABC”,“77”,“键”]

if (Character.isDigit(string.charAt(0))) {

//Do something with int

}

realPK answered 2019-03-31T21:23:56Z

3 votes

您还可以使用Scanner类,并使用hasNextInt() - 这样您也可以测试其他类型,如浮点数等。

Matthew Schinckel answered 2019-03-31T21:24:20Z

2 votes

你只需检查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

}

duggu answered 2019-03-31T21:24:46Z

2 votes

你可以试试apache utils

NumberUtils.isNumber( myText)

在这里查看javadoc

borjab answered 2019-03-31T21:25:17Z

2 votes

这是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

gil.fernandes answered 2019-03-31T21:25:49Z

1 votes

怎么样:

return Pattern.matches("-?\\d+", input);

Kristian answered 2019-03-31T21:26:08Z

1 votes

您可能还需要考虑帐户中的用例:

如果大多数时候您希望数字有效,那么捕获异常只会在尝试转换无效数字时导致性能开销。 而调用某些isInteger()方法然后使用Integer.parseInt()转换将始终导致有效数字的性能开销 - 字符串被解析两次,一次通过检查,一次通过转换。

mobra66 answered 2019-03-31T21:26:40Z

1 votes

这是对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;

}

Wayne answered 2019-03-31T21:27:05Z

1 votes

如果您使用的是Android API,则可以使用:

TextUtils.isDigitsOnly(str);

timxyz answered 2019-03-31T21:27:29Z

1 votes

另外一个选项:

private boolean isNumber(String s) {

boolean isNumber = true;

for (char c : s.toCharArray()) {

isNumber = isNumber && Character.isDigit(c);

}

return isNumber;

}

Gabriel Kaffka answered 2019-03-31T21:27:49Z

1 votes

如果你想检查字符串是否表示适合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;

}

answered 2019-03-31T21:28:15Z

0 votes

is_number = true;

try {

Integer.parseInt(mystr)

} catch (NumberFormatException e) {

is_number = false;

}

Ricardo Acras answered 2019-03-31T21:28:33Z

0 votes

你做了什么,但你可能不应该总是那样检查。 抛出异常应保留用于“特殊”情况(可能适用于您的情况),并且在性能方面非常昂贵。

lucas answered 2019-03-31T21:28:58Z

0 votes

Number number;

try {

number = NumberFormat.getInstance().parse("123");

} catch (ParseException e) {

//not a number - do recovery.

e.printStackTrace();

}

//use number

Ran Biron answered 2019-03-31T21:29:17Z

0 votes

这只适用于正整数。

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;

}

callejero answered 2019-03-31T21:29:42Z

0 votes

这适合我。 只需识别String是基元还是数字。

private boolean isPrimitive(String value){

boolean status=true;

if(value.length()<1)

return false;

for(int i = 0;i

char c=value.charAt(i);

if(Character.isDigit(c) || c=='.'){

}else{

status=false;

break;

}

}

return status;

}

Niroshan Abeywickrama answered 2019-03-31T21:30:06Z

0 votes

要检查所有int chars,您可以简单地使用双重否定。

if(!searchString.matches(“[^ 0-9] + $”))...

[^ 0-9] + $检查是否有任何非整数字符,因此如果测试失败则测试失败。 只是不那样,你就会成功。

Roger F. Gay answered 2019-03-31T21:30:44Z

0 votes

找到这个可能有帮助:

public static boolean isInteger(String self) {

try {

Integer.valueOf(self.trim());

return true;

} catch (NumberFormatException nfe) {

return false;

}

}

shellbye answered 2019-03-31T21:31:09Z

0 votes

我相信在遇到异常时没有风险,因为正如您在下面看到的那样,您总是可以安全地将String解析为float,而不是相反。

所以:

您检查字符串中每个字符槽是否至少匹配其中一个字符{“0”,“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”}。

String

你总结了你在上面的插槽中遇到的所有时间字符。

String

最后你检查你遇到的整数是否为整数字符等于给定字符串的长度。

String

在实践中,我们有:

String aString = "1234224245";

int digits = 0;//count how many digits you encountered

for(int j=0;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

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数据类型),你必须首先检查它是否适合数据类型。 否则你必须施放它。

我希望我帮忙

mark_infinite answered 2019-03-31T21:32:53Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值