之前在code review 的时候,发现有同学直接使用“==”判断两个Integer是否相等,这有问题吗?相信大家对这个都有自己对看法。另外今早上在地铁上听到有人说Integer.parseInt(String s, int radix)返回是int类型,其中radix取值范围是2~36,s长度不能超过7,这种说法对吗?故写此文章来发表自己看法
大家可能对这两个方法用的都比较多,也知道是将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.
*
* In other words, this method returns an {@code Integer}
* object equal to the value of:
*
*
* {@code new Integer(Integer.parseInt(s, radix))}
*
*
* @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.
*
* An exception of type {@code NumberFormatException} is
* thrown if any of the following situations occurs:
*
* - The first argument is {@code null} or is a string of
* length zero.
*
*
- The radix is either smaller than
* {@link java.lang.Character#MIN_RADIX} or
* larger than {@link java.lang.Character#MAX_RADIX}.
*
*
- 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.
*
*
- The value represented by the string is not a value of type
* {@code int}.
*
*
* Examples:
*
* 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
*
*
* @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类型。
上面简单举例说明了两个方法的功能,下面主要对parseInt展开讨论
首先说一下为什么从2开始而不是0或者1或者其他数值。个人分析是小于2的数据只有0/1,如果从1开始,取值只能是0(负数不考虑),不管是0还是00还是几个0,结果都是0,没有什么意义。
另外上限为什么是36,而不是37,64或者其他值。这要从英文说起,目前数字都由0-9组成,额外加26个英文字母,总计正好36个基础元素。2而标点符号是不考虑在内的
上面说到了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默认缓存-128到127的数据,故此范围内使用“==”比较两个对象会返回true。实际上Integer可以缓存更多的数据,可以通过设置-XX:AutoBoxCacheMax=参数来提高缓存数据大小。此外如果是为了比较两个数值大小建议直接使用Integer的parseInt方法,这样可以省去装箱拆箱过程