Integer.parseInt(String s, int radix)和Integer.valueOf(String s, int radix)对比分析

背景

之前在code review 的时候,发现有同学直接使用“==”判断两个Integer是否相等,这有问题吗?相信大家对这个都有自己对看法。另外今早上在地铁上听到有人说Integer.parseInt(String s, int radix)返回是int类型,其中radix取值范围是2~36,s长度不能超过7,这种说法对吗?故写此文章来发表自己看法

Integer.parseInt和Integer.valueOf是做什么的?

大家可能对这两个方法用的都比较多,也知道是将string转换成数字共运算,那什么场景下使用parseInt()?什么场景下使用valueOf()?以下是我个人见解。
首先分别把两个方法对原文注释贴一下

/**
     * Returns an {@code Integer} object holding the value
     * extracted from the specified {@code String} when parsed
     * with the radix given by the second argument. The first argument
     * is interpreted as representing a signed integer in the radix
     * specified by the second argument, exactly as if the arguments
     * were given to the {@link #parseInt(java.lang.String, int)}
     * method. The result is an {@code Integer} object that
     * represents the integer value specified by the string.
     *
     * <p>In other words, this method returns an {@code Integer}
     * object equal to the value of:
     *
     * <blockquote>
     *  {@code new Integer(Integer.parseInt(s, radix))}
     * </blockquote>
     *
     * @param      s   the string to be parsed.
     * @param      radix the radix to be used in interpreting {@code s}
     * @return     an {@code Integer} object holding the value
     *             represented by the string argument in the specified
     *             radix.
     * @exception NumberFormatException if the {@code String}
     *            does not contain a parsable {@code int}.
     */
     public static Integer valueOf(String s, int radix) throws NumberFormatException {
    
    
        return Integer.valueOf(parseInt(s,radix));
    }
/**
     * Parses the string argument as a signed integer in the radix
     * specified by the second argument. The characters in the string
     * must all be digits of the specified radix (as determined by
     * whether {@link java.lang.Character#digit(char, int)} returns a
     * nonnegative value), except that the first character may be an
     * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
     * indicate a negative value or an ASCII plus sign {@code '+'}
     * ({@code '\u005Cu002B'}) to indicate a positive value. The
     * resulting integer value is returned.
     *
     * <p>An exception of type {@code NumberFormatException} is
     * thrown if any of the following situations occurs:
     * <ul>
     * <li>The first argument is {@code null} or is a string of
     * length zero.
     *
     * <li>The radix is either smaller than
     * {@link java.lang.Character#MIN_RADIX} or
     * larger than {@link java.lang.Character#MAX_RADIX}.
     *
     * <li>Any character of the string is not a digit of the specified
     * radix, except that the first character may be a minus sign
     * {@code '-'} ({@code '\u005Cu002D'}) or plus sign
     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
     * string is longer than length 1.
     *
     * <li>The value represented by the string is not a value of type
     * {@code int}.
     * </ul>
     *
     * <p>Examples:
     * <blockquote><pre>
     * parseInt("0", 10) returns 0
     * parseInt("473", 10) returns 473
     * parseInt("+42", 10) returns 42
     * parseInt("-0", 10) returns 0
     * parseInt("-FF", 16) returns -255
     * parseInt("1100110", 2) returns 102
     * parseInt("2147483647", 10) returns 2147483647
     * parseInt("-2147483648", 10) returns -2147483648
     * parseInt("2147483648", 10) throws a NumberFormatException
     * parseInt("99", 8) throws a NumberFormatException
     * parseInt("Kona", 10) throws a NumberFormatException
     * parseInt("Kona", 27) returns 411787
     * </pre></blockquote>
     *
     * @param      s   the {@code String} containing the integer
     *                  representation to be parsed
     * @param      radix   the radix to be used while parsing {@code s}.
     * @return     the integer represented by the string argument in the
     *             specified radix.
     * @exception  NumberFormatException if the {@code String}
     *             does not contain a parsable {@code int}.
     */
    public static int parseInt(String s, int radix)
                throws NumberFormatException

简单翻译一下parseInt和valueOf确实是把字符串转换成十进制的数字,并且支持多种进制(2~36),valueOf调用了parseInt。举例来说Integer.valueOf(123, 8)和Integer.parseInt(123, 8)是把八进制的123转换成10进制的83.不同点在于valueOf返回的是Integer类型,parseInt返回的是int类型。

Integer.parseInt和Integer.valueOf区别及源码分析

上面简单举例说明了两个方法的功能,下面主要对parseInt展开讨论

parseInt(String s, int radix)中的radix取值为什么是2到36

首先说一下为什么从2开始而不是0或者1或者其他数值。个人分析是小于2的数据只有0/1,如果从1开始,取值只能是0(负数不考虑),不管是0还是00还是几个0,结果都是0,没有什么意义。
另外上限为什么是36,而不是37,64或者其他值。这要从英文说起,目前数字都由0-9组成,额外加26个英文字母,总计正好36个基础元素。2而标点符号是不考虑在内的

parseInt(String s, int radix)正常数据范围

上面说到了radix取值范围,那么s的取值范围是否像网友说的不能超过7位么?这里先抛一个结论可以解析的范围是-2147483648(-2^31)
到2147483647(2^31-1).但有一个前提条件就是s中包含的基础字符按顺序排列(0-9 a-z)不能超过radix大小。
贴一下源码,感兴趣可以看看

public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
    
    
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        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;
    }
    

Integer的equals()方法

另外再说一下,很多人都知道Integer默认缓存-128到127的数据,故此范围内使用“==”比较两个对象会返回true。实际上Integer可以缓存更多的数据,可以通过设置-XX:AutoBoxCacheMax=参数来提高缓存数据大小。此外如果是为了比较两个数值大小建议直接使用Integer的parseInt方法,这样可以省去装箱拆箱过程

猜你喜欢

转载自blog.csdn.net/jerry_player/article/details/105556090