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

猜你喜欢

转载自blog.csdn.net/ck3207/article/details/84643710