关于java:如何检查字符串是否为数字

How to check if a string is a number

本问题已经有最佳答案,请猛点这里访问。

我已经转换为核心JAVA中的地图问题。

要求如下:下面给出一个字符串数组

1
String str[] = {"abc","123","def","456","ghi","789","lmn","101112","opq"};

将其转换为映射,使结果输出低于

产量

1
2
3
4
5
6
7
======      ======        
key         Value        
======      ======                  
abc          true      
123          false      
def          true      
456          false

应为数组中的每个元素打印上述内容。我写了代码,但它不起作用,我被卡住了。请告诉我怎么解决。事先谢谢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.HashMap;      
import java.util.Iterator;      
import java.util.Map;      

public class CoversionToMap {

/**
 * @param args
 */

public static void main(String[] args) {
    String str[] = {"abc","123","def","456","ghi","789","lmn","101112","opq"};
    Map m = new HashMap();
    for(int i=0;i<str.length;i++){
        if(Integer.parseInt(str[i]) < 0){
            m.put(str[i],true);
        }else{
            m.put(str[i],false);
        }
    }
    //Print the map values finally
    printMap(m);
}  

public static void printMap(Map mp) {
        Iterator it = mp.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry)it.next();          
            System.out.println(pairs.getKey() +" =" + pairs.getValue());
        }
}  
}

例外情况:

1
2
3
4
5
Exception in thread"main" java.lang.NumberFormatException: For input string:"abc"      
    at java.lang.NumberFormatException.forInputString(Unknown Source)      
    at java.lang.Integer.parseInt(Unknown Source)      
    at java.lang.Integer.parseInt(Unknown Source)      
    at CoversionToMap.main(CoversionToMap.java:22)


每个人都建议对此使用异常处理,这里没有任何异常可以保证使用这样的异常,你不会尝试在车里左转,如果你撞车了,你会右转吗?像这样的事情应该可以做到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Map<String, Boolean> m = new HashMap<String, Boolean>();
for (String str: strs) {
    m.put(str, isInteger(str));
}

public boolean isInteger(String str) {
    int size = str.length();

    for (int i = 0; i < size; i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return false;
        }
    }

    return size > 0;
}

更清楚,更有效的捕捉抛出异常,即使有99%的整数作为整数值甚至不需要,所以不需要转换。


Integer.parseInt(..)对无效输入抛出异常。

您的if条款应如下所示:

1
2
3
4
5
if (isNumber(str[i])) {
   ...
} else {
   ...
}

其中isNumber可以通过多种方式实现。例如:

  • 使用try { Integer.parseInt(..) } catch (NumberFormatException ex)(见相关问题)
  • 使用通用语言NumberUtils.isNumber(..)


如果您想检查该字符串是否是有效的Java数字,您可以使用EDCOX1的方法2从EDCOX1 7中得出(doc:http://cords.orache .org/Lang/APi-2.4/org/Apache/Caluns/Lang/Matry/NoMultuuts.html)。

这样,您就不必编写自己的isNumber实现了。


检查parseInt是否返回小于0的数字,以查看输入是否为非数字。

但是,如果输入是非数字的,那么该方法根本不返回任何值。相反,它抛出了一个异常,如您所见。

做你想做的事情的最简单的方法是捕获那个异常并相应地采取行动:

1
2
3
4
5
6
try {
  Integer.parseInt(str[i]);
  // str[i] is numeric
} catch (NumberFormatException ignored) {
  // str[i] is not numeric
}


这里有一个改进的答案,可以用于负数、小数点等,它使用Regular Expressions

这里是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class StringValidator {

    public static void printMap(Map<String, Boolean> map) {
        Iterator it = map.entrySet().iterator();
        for(Map.Entry<String, Boolean> entry:map.entrySet()){
            System.out.println(entry.getKey()+" ="+ entry.getValue());
        }
    }
}

class ValidateArray{
        public static void main(String[] args) {
        String str[] = {"abcd","123","101.112","-1.54774"};
        Map<String, Boolean> m = new HashMap<String, Boolean>();
        for (String s : str) {
            m.put(s, isNumber(s));
        }
        StringValidator.printMap(m);
    }

    public static boolean isNumber(String str) {
        Pattern pattern = Pattern.compile("^-?\\d+\\.?\\d*$");
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
}


假设您不使用任何外部库,也可以使用正则表达式匹配器来实现这一点。就像

1
2
3
for (String element : str) {
     m.put(element, element.matches("\\d+"));
}

注意,这只适用于非负整数,但是您可以调整正则表达式以匹配要映射为true的数字格式。另外,如果元素是null,您将得到NullPointerException,因此这里需要一些防御代码。


此处出现错误:

1
if(Integer.parseInt(str[i]) < 0){

integer.parseint在输入不是数字时抛出一个numberFormatException,因此需要使用try/catch块,例如:

1
2
3
4
5
6
try{
    int number = Integer.parseInt(str[i]);
    m.put(str[i],false);
}catch NumberFormatException nfe{
    m.put(str[i],true);
}


您需要使用try/catch块,而不是测试parseint的返回值。

1
2
3
4
5
6
try {
    Integer.parseInt(str[i]);
    m.put(str[i],true);
} catch(NumberFormatException e) {
    m.put(str[i],false);
}


这里有一个更通用的方法来验证、避免异常以及使用格式子类已经知道的内容。例如,simpledateformat知道2月31日是无效的,只要你告诉它不要宽容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

public class ValidatesByParsePosition {

    private static NumberFormat _numFormat = NumberFormat.getInstance();
    private static SimpleDateFormat _dateFormat = new SimpleDateFormat(
           "MM/dd/yyyy");

    public static void printMap(Map<String, Boolean> map) {

        for (Map.Entry<String, Boolean> entry : map.entrySet()) {
            System.out.println(entry.getKey() +" =" + entry.getValue());
        }
    }

    public static void main(String[] args) {

        System.out.println("Validating Nums with ParsePosition:");
        String numStrings[] = {"abcd","123","101.112","-1.54774","1.40t3" };
        Map<String, Boolean> rslts = new HashMap<String, Boolean>();
        for (String s : numStrings) {
            rslts.put(s, isOk(_numFormat, s));
        }
        ValidatesByParsePosition.printMap(rslts);

        System.out.println("
Validating dates with ParsePosition:"
);
        String dateStrings[] = {"3/11/1952","02/31/2013","03/14/2014",
               "05/25/2014","3/uncle george/2015" };
        rslts = new HashMap<String, Boolean>();
        _dateFormat.setLenient(false);
        for (String s : dateStrings) {
            rslts.put(s, isOk(_dateFormat, s));
        }
        ValidatesByParsePosition.printMap(rslts);
    }

    public static boolean isOk(Format format, String str) {

        boolean isOK = true;
        int errorIndx = -1;
        int parseIndx = 0;

        ParsePosition pos = new ParsePosition(parseIndx);

        while (isOK && parseIndx < str.length() - 1) {
            format.parseObject(str, pos);
            parseIndx = pos.getIndex();
            errorIndx = pos.getErrorIndex();
            isOK = errorIndx < 0;
        }

        if (!isOK) {
            System.out.println("value "" + str
                    +"
" not parsed; error at char index" + errorIndx);
        }

        return isOK;
    }

}


我想在这里输入"不要使用异常处理"的相反观点。以下代码:

1
2
3
4
5
6
7
8
try
{
  InputStream in = new FileInputStream(file);
}
catch (FileNotFoundException exc)
{
  // ...
}

完全等同于:

1
2
3
4
5
6
7
8
9
10
11
12
13
if (!file.exists())
{
  // ...
}
else
try
{
  InputStream in = new FileInputStream(file);
}
catch (FileNotFoundException exc)
{
 // ...
}

除前一种情况外:

  • 文件的存在只检查一次
  • 两次检查之间没有时间窗口,在这期间情况可能发生变化。
  • 在//…只编程一次。
  • 所以你看不到第二种情况下的代码。至少你不应该。

    目前的情况是相同的,只是因为它是一个String没有时间窗口。Integer.parseInt()无论如何都必须检查输入的有效性,它抛出了一个异常,无论如何都必须在某个地方捕获(除非您喜欢RTE停止线程)。那为什么每件事都要做两次呢?

    您不应将异常用于正常流控制的反驳论点只是回避了这个问题。流量控制正常吗?还是输入错误?[事实上,我一直理解这一原则,更具体地说,在方法中"不要将异常抛出到您自己的代码中",即使这样,当它是最好的答案时,也很少会出现这种情况。我不喜欢任何形式的笼统规则。]

    另一个在ObjectInputStream上检测eof的例子。你是通过抓到EOFException来做到的。除了在流中预先混合一个计数之外,没有其他方法,这是一个设计更改和格式更改。那么,EOF是正常流程的一部分,还是一个例外?如果它只是通过一个异常报告的,那么它怎么可能是正常流的一部分呢?


    将parseint行替换为对isinteger(str[i])的调用,其中isinteger的定义为:

    1
    2
    3
    4
    5
    6
    7
    8
    public static boolean isInteger(String text) {
      try {
        new Integer(text);
        return true;
      } catch (NumberFormatException e) {
        return false;
      }
    }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    boolean intVal = false;
        for(int i=0;i<str.length;i++) {
                intVal = false;
                try {
                    if (Integer.parseInt(str[i]) > 0) {
                        intVal = true;
                    }
                } catch (java.lang.NumberFormatException e) {
                    intVal = false;
                }
            m.put(str[i], !intVal);
        }