1. 程式人生 > >java初學者——坑王(一)

java初學者——坑王(一)

最近在學java,做一個課堂作業——實現16進位制數轉換成10進位制數。然後擼了以下程式碼:

	/**
	 * 16進位制轉換成10進位制
	 * @param hex	16進位制傳參
	 * @return		返回10進位制整數
	 */
	public static int HexToDec(String hex){
//		int[] array = {10, 11, 12, 13, 14, 15};
		int decNum = 0;
		for(int i=0; i<hex.length(); i++){
			char tempChar = hex.charAt(i);
			if (tempChar >= '0' && tempChar <= '9'){
				int tempValue = (int)(tempChar);
				decNum = decNum + tempValue * 16^(hex.length() - i - 1);
			}else if("A".equals(tempChar)){
				decNum = decNum + 10 * 16^(hex.length() - i - 1);
			}else if("B".equals(tempChar)){
				decNum = decNum + 11 * 16^(hex.length() - i - 1);
			}else if("C".equals(tempChar)){
				decNum = decNum + 12 * 16^(hex.length() - i - 1);
			}else if("D".equals(tempChar)){
				decNum = decNum + 13 * 16^(hex.length() - i - 1);
			}else if("E".equals(tempChar)){
				decNum = decNum + 14 * 16^(hex.length() - i - 1);
			}else if("F".equals(tempChar)){
				decNum = decNum + 15 * 16^(hex.length() - i - 1);
			}
		}
		return decNum;
	}

寫完以後,自我覺得雖然程式碼不夠簡潔吧,至少功能應該是ok的。沒想到一執行、除錯,發現了各種問題。讓隔壁做後端開發的室友看了看,這小夥竟然沒發現出什麼問題。看來這裡有個大坑…
程式碼比較簡單,各位大神應該都在我至少,就不班門弄斧講解了。
通過排查,最後發現這段程式碼中有三個坑。

字元型別強制轉成整型

案例中,有一段程式碼是將字元型別強制轉成整型,粗略一看沒啥問題。除錯過程中,tempChar為’4’, 通過以下程式碼轉換:

int tempValue = (int)(tempChar);

得到結果tempValue為52。說實話,當時看到這個結果是懵逼的,都要懷疑人生了。後經他人點播,字元’4’的askii碼轉成整形為52;aksii


也就是說,java中,字元型別強制轉成整型得到的是:askii碼錶中,字元對應的十進位制值。
上述程式碼如何改善呢,可以根據askii碼錶中 傳入字元與’0’的距離來得到值:

int tempValue = (int)(tempChar + '0');

N次方

如果你還記得16進位制轉成10進位制的演算法,那麼這段計算方法你不會陌生:

16^(hex.length() - i - 1)

我想得到是:16的(hex.length() - i - 1)次方。可能這個符號^用的較少,這個符號並不是取次方。^這個符號其實代表的是異或。難怪執行16^1的結果是17。除錯的時候第二次懷疑人生。道行尚淺啊!

字元比較

16進位制會包含字母A/B/C/D/E/F,程式碼中也做了特殊處理。比較方式如下:

"?".equals(tempChar) 	# ? 代表A/B/C/D/E/F

本來麼,我應該會用==號,但想起前幾天視訊中說過,字串比較用equals方法比較專業,並且常量在前,變數在後會更好。話是記住了,除錯時卻遇到麻煩了。明明看到的是’E’,但是就是進不去條件內部。後面改成 :

"?" == tempChar 	# ? 代表A/B/C/D/E/F

功能正常,符合預期。
通過查閱文件,發現了問題的根源:

java中的資料型別,可分為兩類:
1,基本資料型別,也稱原始資料型別。byte,short,char,int,long,float,double,boolean 他們之間的比較,應用雙等號(==),比較的是他們的值。

2,複合資料型別(類),當他們用(==)進行比較的時候,比較的是他們在記憶體中的存放地址,所以,除非是同一個new出來的物件,他們的比較後的結果為true,否則比較後結果為false。JAVA當中所有的類都是繼承於Object這個基類的,在Object中的基類中定義了一個equals的方法,這個方法的初始行為是比較物件的記憶體地 址,但在一些類庫當中這個方法被覆蓋掉了,如String,Integer,Date在這些類當中equals有其自身的實現,而不再是比較類在堆記憶體中的存放地址了。 
對於複合資料型別之間進行equals比較,在沒有覆寫equals方法的情況下,他們之間的比較還是基於他們在記憶體中的存放位置的地址值的,因為Object的equals方法也是用雙等號(==)進行比較的,所以比較後的結果跟雙等號(==)的結果相同。
上述引用來自:https://blog.csdn.net/qiuyoungster/article/details/53052854