java实现字符串转化为整数

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来求。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。