Integer.valueOf(String s)源码解读

刷leetcode正好刷到了字符串转int的题目,就看了看java源码是如何实现的,借鉴一下思路。

核心是parseInt(),至于Integer.valueOf()只是做了一个[-128,127]的常量池。


Integer.valueOf()

全部代码粘贴如下,去除了s空串与radix非法范围的异常校验。

public static int parseInt(String s, int radix)
            throws NumberFormatException
{
    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;
}

整体思路也好理解,字符串从左到右扫描,result从0开始,每读取1位新字符,等于进位一次,所以乘以进制。再减去digit。
举例说明读取“123”,result变化是0,-1,-12,-123。

这里主要聊聊result为什么采用减法而不是加法计算,以及边界值判定。

1.result采用减法而不是加法计算,就是为了让result变成一个负数。因为int是有符号数字,范围是[-2^31~2^31-1]。负数比正数多一位。如果result用正数存储,那么就不能存储2^31。也就没办法表示-2^31。

2.边界值判定
边界值判定依靠两个值,一个是limit,另一个是multmin。首先是limit选取,正数范围应该是2^31-1。因为计算过程变成负数,所以这里取-(2^31-1)。负数是-2^31,不用变。这里还有个注意点是比较顺序,result < limit + digit 的判断应该放在result -= digit;之前,否则运算完就直接溢出,判断不出来了。然后是multmin。为什么在limit之外还需要判断,因为result *= radix;也可能导致溢出。multmin是limit右移一位的值。这里直接举数字说明。int最多能存储-2147483648。如果出现-5555555555就不行。反向思维一下,最后一位没有读取前int能接收最大数字要在[-214748364,0]之间。至于-2147483649的合法性问题就是limit来判定的。同样,multmin的判断也要在result *= radix运算前面。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • The Integer class wraps a value of the primitive type int...
    0x70e8阅读 522评论 0 0
  • java.lang.Integer#parseInt() 源码分析 Integer#parseInt() 是我们经...
    mlya阅读 893评论 2 0
  • 最近在准备春招,刷到这样一道题“string 转换成 integer的方式及原理”,于是翻了翻源码,简单记录一下。...
    Xun_Moo阅读 361评论 0 0
  • 其他更多java基础文章:java基础学习(目录) 转载自 Java 源码学习系列(三)——Integer学习的过...
    Hiwayz阅读 698评论 0 0
  • Integer源码阅读: parseInt函数: 函数声明:public static int parseInt(...
    TailWU阅读 204评论 0 1