String转Integer源码简析

最近在准备春招,刷到这样一道题“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;’

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

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 最先接触编程的知识是在大学里面,大学里面学了一些基础的知识,c语言,java语言,单片机的汇编语言等;大学毕...
    oceanfive阅读 8,381评论 0 7
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 9,698评论 0 13
  • 在很多对于美容师或是市场导师的训练之后,都可以明显地发现,很多原来讲话很小声的变大声了;原来不敢开口的变成敢开口了...
    周明达老师阅读 4,952评论 2 11
  • 那年的8月,相遇的没有一点点预兆,没有传说中的一见钟情,也没有怦然心动,也没想过以后,更没预料到,半个月后的我,会...
    super樱阅读 1,007评论 0 1
  • 【2017-7-14 周五】 明明早上还是晴空万里 午间忽然就下起了大雨 就是那种风卷着雨水肆意挥洒的场景 还好早...
    白爷Mocha阅读 988评论 0 0