美文网首页
String转Integer源码简析

String转Integer源码简析

作者: Xun_Moo | 来源:发表于2018-03-07 20:04 被阅读0次

最近在准备春招,刷到这样一道题“string 转换成 integer的方式及原理”,于是翻了翻源码,简单记录一下。

valueOf方法定义如下,可以看到方法中直接调用了parseInt,并默认使用十进制转换


public static Integer valueOf(String s) throws NumberFormatException {

        return Integer.valueOf(parseInt(s, 10));

    }

接下来详细看一下parseInt方法


public static int parseInt(String s, int radix) throws NumberFormatException

    {

        if (s == null) { 

            throw new NumberFormatException("null");

        }

        if (radix < Character.MIN_RADIX) {

            throw new NumberFormatException("radix " + radix +

                                            " less than Character.MIN_RADIX");

        }

        if (radix > Character.MAX_RADIX) {

            throw new NumberFormatException("radix " + radix +

                                            " greater than Character.MAX_RADIX");

        }

        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 != '+')

                    throw NumberFormatException.forInputString(s);

                if (len == 1) // Cannot have lone "+" or "-"

                    throw NumberFormatException.forInputString(s);

                i++;

            }

            multmin = limit / radix;

            while (i < len) {

                // Accumulating negatively avoids surprises near MAX_VALUE

                digit = Character.digit(s.charAt(i++),radix);

                if (digit < 0) {

                    throw NumberFormatException.forInputString(s);

                }

                if (result < multmin) {

                    throw NumberFormatException.forInputString(s);

                }

                result *= radix;

                if (result < limit + digit) {

                    throw NumberFormatException.forInputString(s);

                }

                result -= digit;

            }

        } else {

            throw NumberFormatException.forInputString(s);

        }

        return negative ? result : -result;

    }

实现思路整理如下

  • 判断字符串是否为null,若为null则直接抛出异常。

  • 判断进制是否超出范围(小于2或大于36)

  • 当字符串长度大于0时,先判断是否起于‘-’或者‘+’符号,并排除单符号情况

  • 遍历字符串,利用Character.digit方法将char转换成int,并加到记录结果的result变量上。在这里进行了三次检查

    • if (digit < 0):非法字符,无法转换成int

    • if (result < multmin):为‘result *= radix;’语句做准备,避免溢出。这里multmin = limit / radix;

    • if (result < limit + digit):为‘result -= digit;’语句做准备,避免溢出。注意这里不能写成‘result- digit < limit;’

  • 最后判断正负并返回结果

注意到一点,该方法在计算过程中所有数据均按照负数处理。个人觉得主要是简化了计算情况,同时只需要检查单边界。

相关文章

网友评论

      本文标题:String转Integer源码简析

      本文链接:https://www.haomeiwen.com/subject/kcysfftx.html