Situation:
在只能存储 32 位大小的有符号整数的环境背景下,给定一个字符串,将其转换为整数。
字符串 → 整数
将字符串参数作为有符号的十进制整数进行解析
Java parseInt()
JDK 中不得不提 Integer Class 的 parseInt() 方法
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");
}
//一般情况下,编程的基础类库支持2进制到36进制。
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;
//flag to determine whether it is negative
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
//Determine whether it overflows every time a new number is added
int multmin;
//current value
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;
}
【注】:
以上是源码,已通过注释解析
Add Condition
在 Situation 基础上添加条件:
字符串中包含 空格 " "、非数字字符 “a ~ z” OR “A ~ Z”
给定一个测试用例: " -42" 【" “+”-"+“4”+“2”】
此时 Java parseInt( ) 便行不通了,错误如下:
Exception in thread "main" java.lang.NumberFormatException: For input string: " -42"
Analysis:
这个方法无法处理前导空格,当然可以自己实现下这个方法,加入前导空格的判断,直接移动索引到第一个有效字符处。
同名同姓的他,在JavaScript 中却截然不同…
JavaScript parseInt()
解析一个字符串,返回一个整数
- 可以处理不同进制。 e.g.:以 0x 开头的被解析为十六进制、以 o 开头的被解析为八进制 / 十六进制;
- 可以处理前导空格。有效字符串前面和结尾的空格是允许的;
- 可以处理第一个字符非数字型字符串。第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。
也暗示着只有字符串中第一个可以转换的数字会被返回
Conclusion:
来自 LeetCode 8.的思考,更是源于一道曾经的面试题
【当然对于这个情境有更好的处理方式,正则、位操作…etc.】
同为 parseInt( ),相比起来,Java 中的效果貌似要劣于 JS 中的。
Point:
- 前导空格和有效字符串结尾空格;
- 2 ~ 36之间的不同进制;
- 非有效字符(not in “1” ~ “9”)。