完美数判断方法中相同数值的if条件为何返回false?
完美数判断方法中数值比较失效的原因
先看你提供的代码:
public static Boolean parfait(Integer k) { Integer s = 0; for (Integer i = 1; i < k; i++) { if (k % i == 0) { s=s+i; System.out.println(i); //return true; } } System.out.println("sum:"+s); System.out.println("val:"+k); if(s==k){// why 496 != 496 return true; }else{ return false; } }
System.out.println("Nombre parfait: " + parfait(496));
问题的核心在于你使用了Integer包装类而非int基本类型,并且用==来判断数值是否相等。
原因解析:
Java为了优化性能,会对Integer类型在**-128到127**范围内的数值进行缓存。当你传入6、28这类在缓存范围内的数值时,自动装箱生成的Integer对象会复用缓存里的实例,此时==比较的是对象引用,因为是同一个对象,所以会返回true。
但当数值超过这个范围(比如496、8128)时,每次自动装箱都会创建新的Integer对象。这时==比较的是两个不同对象的引用地址,自然返回false——哪怕它们的数值完全相同,你打印出来的s和k数值一致,但它们是两个独立的Integer实例,引用地址并不相等。
解决办法:
有三种可行的修改方式:
- 改用
int基本类型:把方法参数、变量s和i都改成int,这样==直接比较数值,不会有引用问题:
public static boolean parfait(int k) { int s = 0; for (int i = 1; i < k; i++) { if (k % i == 0) { s += i; System.out.println(i); } } System.out.println("sum:" + s); System.out.println("val:" + k); return s == k; }
- 用
equals()方法比较Integer对象:Integer的equals()方法会直接比较两个对象的数值,而非引用:
if(s.equals(k)){ return true; }else{ return false; }
或者更简洁的写法:return s.equals(k);
- 提取基本类型后比较:调用
intValue()获取Integer对象对应的基本类型数值,再用==比较:
if(s.intValue() == k.intValue()){ return true; }else{ return false; }
内容的提问来源于stack exchange,提问作者Liudmyla Lahoida
相关产品推荐
相关产品推荐

