1、思路及注意事项
概括起来有几种情况
1)字符串开头是“+”号或“-”号的处理
2)非法字符的判断(不是数字)
3)整数溢出问题。
看看Java函数库中的Integer.parseInt(String sting)的源码如何处理这些问题的。
- /**
- * Parses the specified string as a signed decimal integer value. The ASCII
- * character \u002d ('-') is recognized as the minus sign.
- *
- * @param string
- * the string representation of an integer value.
- * @return the primitive integer value represented by {@code string}.
- * @throws NumberFormatException
- * if {@code string} cannot be parsed as an integer value.
- */
- public static int parseInt(String string) throws NumberFormatException {
- return parseInt(string, 10);
- }
- /**
- * Parses the specified string as a signed integer value using the specified
- * radix. The ASCII character \u002d ('-') is recognized as the minus sign.
- *
- * @param string
- * the string representation of an integer value.
- * @param radix
- * the radix to use when parsing.
- * @return the primitive integer value represented by {@code string} using
- * {@code radix}.
- * @throws NumberFormatException
- * if {@code string} cannot be parsed as an integer value,
- * or {@code radix < Character.MIN_RADIX ||
- * radix > Character.MAX_RADIX}.
- */
- public static int parseInt(String string, int radix) throws NumberFormatException {
- if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
- throw new NumberFormatException("Invalid radix: " + radix);
- }
- if (string == null) {
- throw invalidInt(string);
- }
- int length = string.length(), i = 0;
- if (length == 0) {
- throw invalidInt(string);
- }
- boolean negative = string.charAt(i) == '-';
- if (negative && ++i == length) {
- throw invalidInt(string);
- }
- return parse(string, i, radix, negative);
- }
- private static int parse(String string, int offset, int radix, boolean negative) throws NumberFormatException {
- int max = Integer.MIN_VALUE / radix;
- int result = 0, length = string.length();
- while (offset < length) {
- int digit = Character.digit(string.charAt(offset++), radix);
- if (digit == -1) {
- throw invalidInt(string);
- }
- if (max > result) {
- throw invalidInt(string);
- }
- int next = result * radix - digit;
- if (next > result) {
- throw invalidInt(string);
- }
- result = next;
- }
- if (!negative) {
- result = -result;
- if (result < 0) {
- throw invalidInt(string);
- }
- }
- return result;
- }
parseInt(String string, int radix)判断了
1)radix进制超出范围(
Character.
MIN_RADIX
=
2,
Character.
MAX_RADIX
)=36)
2)字符串为null
3)字符串长度为空
4)字符串第一位为“-”且只有一位
没有异常之后进行parse(String string, int offset, int radix, boolean negative)判断,参数即字符串,偏移量,进制,negative(如果开头没有“-”则offset=0,negative=false,否则为offset=1,neagtive=true)
在parse(String string, int offset, int radix, boolean negative)主要进行了溢出的判断。利用offset++来控制移动, 在while (offset < length) 循环中直到倒数第二位的时候,如果已经小于 max = Integer.MIN_VALUE / radix的话表明一定会溢出。例如"-2147483648"
倒数第二位的时候
:result=-214748364,max=-214748364,max>result不成立表明可以进行最后一位的处理。
这里为什么不先求得当前的结果再同Integer.MIN_VALUE比较?而是先同Integer.MIN_VALUE / radix比较再决定是否进行下一位的添加?不言而喻。
2、参考源码实
现字符串转化为整数
- public class StringToIntTest {
- /**
- * @author 曹艳丰 北京大学
- */
- public static void main(String[] args) {
- // TODO 自动生成的方法存根
- try {
- System.out.println(parseInt("cao21'''474fefda8364fe7"));
- System.out.println(parseInt("-2147483648"));
- System.out.println(parseInt("-2147483651"));
- System.out.println(parseInt("-2147483648"));
- System.out.println(parseInt("-21474836410"));
- } catch (MyException e) {
- // TODO 自动生成的 catch 块
- e.printStackTrace();
- }
- }
- private static int parseInt(String string) throws MyException {
- /* 异常情况1:字符串为null */
- if (string == null) {
- throw new MyException("字符串为null!");
- }
- int length = string.length(), offset = 0;
- /* 异常情况2:字符串长度为0 */
- if (length == 0) {
- throw new MyException("字符串长度为0!");
- }
- boolean negative = string.charAt(offset) == '-';
- /* 异常情况3:字符串为'-' */
- if (negative && ++offset == length) {
- throw new MyException("字符串为:'-'!");
- }
- int result = 0;
- char[] temp = string.toCharArray();
- while (offset < length) {
- char digit = temp[offset++];
- if (digit <= '9' && digit >= '0') {
- int currentDigit = digit - '0';
- /*
- * 异常情况4:已经等于Integer.MAX_VALUE / 10,判断要添加的最后一位的情况:
- * 如果是负数的话,最后一位最大是8 如果是正数的话最后一位最大是7
- */
- if (result == Integer.MAX_VALUE / 10) {
- if ((negative == false && currentDigit > 7)
- || (negative && currentDigit > 8)) {
- throw new MyException("溢出!");
- }
- /*
- * 异常情况5:已经大于Integer.MAX_VALUE / 10
- * 无论最后一位是什么都会超过Integer.MAX_VALUE
- */
- } else if (result > Integer.MAX_VALUE / 10) {
- throw new MyException("溢出!");
- }
- int next = result * 10 + currentDigit;
- result = next;
- }
- }
- if (negative) {
- result = -result;
- }
- return result;
- }
- }
- /* 自定义异常 */
- class MyException extends Exception {
- /**
- *
- */
- private static final long serialVersionUID = 1749149488419303367L;
- String message;
- public MyException(String message) {
- // TODO 自动生成的构造函数存根
- this.message = message;
- }
- @Override
- public String getMessage() {
- // TODO 自动生成的方法存根
- return message;
- }
- }
“如果是负数的话,最后一位最大是8 如果是正数的话最后一位最大是7”可以用Integer.MIN_VALUE%10和Integer.MAX_VALUE%10来求。
转自:http://blog.csdn.net/brillianteagle/article/details/39029351?utm_source=tuicool