先看再點贊,給自己一點思考的時間,微信搜索【沉默王二】關注這個有顏值卻假裝靠才華茍且的程式員,
本文 GitHub github.com/itwanger 已收錄,里面還有我精心為你準備的一線大廠面試題,
之前我寫了一篇《老師,你確定Java注釋不會被執行嗎》,結果文章在知乎小火了一把,將近 10 萬人閱讀,有愛裝逼的同行批評說,標題夸大了; 同時,也有很多初學者表示,漲見識了,之前從來不知道這個知識點,這下學到了,
必須得承認一點,我寫的大多數技術文章都是針對初學者的,因為我覺得他們最需要幫助,這也是我一直堅持分享的初衷,
我也不喜歡寫那些高深的文章,費時間耗精力,受眾也小,就拿我們學過的古詩來說吧,“鵝鵝鵝,曲項向天歌”,“一去二三里,煙村四五家”,我就覺得挺好的,沒必要都去搞陽春白雪,最后搞得曲高和寡,對吧?
那這次來分享一個新的知識點,我敢賭一包衛龍辣條(打錢來),很多同學不一定知道,
在 Java 中,String(字串) 和 int(整形) 是兩種不同的資料型別,字串可以把許多字串起來,整形嘛——就是整形了,
(同學們可能會疑惑,這個知識點我能不知道,別蒙我好不好?繼續往下看唄,吃大餐之前,還能不來點小吃或者涼菜?)
有時候,字串可以單純包含一些數字,比如說“123”,大家應該都見過,當一些操作需要你輸入手機驗證碼的時候,大部分要求輸入的都是 6 位或者 4 位的亂數字,它們傳遞到服務器端的時候,最初的形式都是字串型別的,然后可能再轉成整形做一些處理,
對于 Java 來說,不能直接通過“+”運算子來使兩個字串型別的數字相加,來看下面的例子,
String a = "100";
String b = "50";
String c = a+b;
System.out.println(c);
程式輸出的結果是 10050,而不是 150,對于字串來說,“+”運算子是用來串聯的,而不是用來相加的,
(同學們可能又要催了,這個知識點我也知道啊!馬上馬上,重點馬上就來,)
那就有必要先把字串轉成整形再來做運算了,常見的做法有兩種:
第一種,使用 Integer.valueOf(),它將回傳一個包裝器型別 Integer,當然可以通過自動拆箱的方式將其轉成 int 型別,
String a = "100";
String b= "50";
int A = Integer.valueOf(a);
int B = Integer.valueOf(b);
int c = A+B;
System.out.println(c);
程式輸出結果如下所示:
150
第二種,使用 Integer.parseInt(),它將回傳一個基本資料型別 int,
String a = "100";
String b= "50";
int A = Integer.parseInt(a);
int B = Integer.parseInt(b);
int c = A+B;
System.out.println(c);
程式輸出結果如下所示:
150
這兩種方式,優先推薦第二種,因為不涉及到自動拆箱,性能更佳,
(同學們可能急不可耐了,就這?好了,現在重點真的來了)
那除了上面這兩種方式,同學們還能想到第三種嗎?把字串轉成整形,是不是突然感覺腦袋里有點空?
空就對了,本篇文章最漲見識的時候,它來了!步履蹣跚地來了!
/**
* @author 沉默王二,一枚有趣的程式員
*/
public class String2IntDemo {
public static void main(String[] args) {
String a = "100";
String b = "50";
int A = string2int(a);
int B = string2int(b);
int c = A + B;
System.out.println(c);
}
public static int string2int(String s) {
int num = 0;
int pos = 1;
for (int i = s.length() - 1; i >= 0; i--) {
num += (s.charAt(i) - '0') * pos;
pos *= 10;
}
return num;
}
}
這段程式輸出的結果同樣是 150,那眼睛雪亮的同學可能就發現了,string2int() 方法到底是個什么樣的神奇方法,還有把字串轉成整形的功效?
首先,必須得普及一點常識,同學們需要對 ASCII 碼有一點了解,就是所有的字符都有識別它們的代碼——這代碼就是 ASCII 碼,
基于這一點,所有數字型的字符減去字符‘0’,將會得到該字符的絕對值,是一個整數,
String s = "520";
System.out.println(s.charAt(2) - '0');
System.out.println(s.charAt(1) - '0');
System.out.println(s.charAt(0) - '0');
輸出結果如下所示:
0
2
5
字串“520”的長度為 3,也就是說,下標為 2 的位置是字符‘0’——數字 520 的個位數;下標為 1 的位置是字符‘2’——數字 520 的十位數;下標為 0 的位置是字符‘5’——數字 520 的百位數,
那有些機靈點的同學可能就想到了,通過一個 for 回圈,遍歷一下字串,然后計算出當前位置上的整數值,個位數乘以 1,十位數乘以 10,百位數乘以 100,然后再加起來,就是字串對應的整數值了,
沒錯,沒錯,string2int() 方法就是這么做的,如果引數是字串“520”,那回傳的結果就是整形 520;如果引數是字串“100”,那回傳的結果就是整形 100;如果引數是字串“50”,那回傳的結果就是整形 50,
如果你是一名有追求的程式員,那么對于 Integer.valueOf() 和 Integer.parseInt() 都不會太滿意,因為這只是拿別人的輪子來用,而自定義方法 string2int() 就屬于從頭到尾的造輪子了,一想到這,是不是感覺自己開始變牛逼了?
其實,如果你肯扒拉原始碼的話,就會恍然大悟,
先來看 Integer.valueOf() 方法:
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
內部呼叫的其實就是 int parseInt(String s, int radix) 方法,
再來看 Integer.parseInt() 方法:
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
內部呼叫的也是 int parseInt(String s, int radix) 方法,基數 radix 引數都是 10——同學們是不是猜到了什么?
對,你猜的八九不離十,再來看一下 int parseInt(String s, int 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");
}
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
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, radix);
}
if (len == 1) { // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s, radix);
}
i++;
}
int multmin = limit / radix;
int result = 0;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i++), radix);
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s, radix);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s, radix);
}
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString(s, radix);
}
}
1)parseInt() 方法判斷了 null 的情況,認為格式不正確,
2)然后判斷了基數 radix 的情況,不能小于 2,不能大于 36,
3)if (len > 0) 判斷了字串長度的情況,如果為空“”,也認為格式不正確,
4)再然后判斷首個字符 s.charAt(0),如果是負號“-”則認為當前字串是一個負數;如果不是正號“+”,則認為格式不正確;如果只有一個負號或者正號,也認為格式不正確,
總之,就是比我們的自定義方法 string2int() 更嚴謹,
5)使用 while 回圈,配合更專業的 Character.digit(s.charAt(i++), radix) 計算出每個位置上字符對應的數值,然后和基數 radix 進行相乘后使用累減的方式計算出最后的數值,
和 string2int() 有點不同,但整體上思路是一致的,
我們也可以對 string2int() 方法再完善一下,使其滿足負數的情況:
public class S2IDemo {
public static void main(String[] args) {
String a = "-100";
String b = "50";
int A = string2int(a);
int B = string2int(b);
int c = A + B;
System.out.println(c);
}
public static int string2int(String s) {
boolean negative = false;
char firstChar = s.charAt(0);
if (firstChar == '-') {
negative = true;
s = s.substring(1);
}
int num = 0;
int pos = 1;
for (int i = s.length() - 1; i >= 0; i--) {
num += (s.charAt(i) - '0') * pos;
pos *= 10;
}
return negative ? -num : num;
}
}
當首個字符為負號‘-’的話,結果就回傳負數,并且把原來的字串截取掉第一位,其他不變,這時候,當 a 為“-100”,b 為“50”的時候,a + b 的結果就是 -50,
我就問一句,造輪子的感覺是不是很爽?反正我已經爽過了,
我是沉默王二,一枚有顏值卻假裝靠才華茍且的程式員,關注即可提升學習效率,別忘了三連啊,點贊、收藏、留言,我不挑,奧利給??,
注:如果文章有任何問題,歡迎毫不留情地指正,
如果你覺得文章對你有些幫助,歡迎微信搜索「沉默王二」第一時間閱讀,回復關鍵字「小白」可以免費獲取我肝了 4 萬+字的 《Java 小白從入門到放肆》2.0 版;本文 GitHub github.com/itwanger 已收錄,歡迎 star,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/75537.html
標籤:Java
