关于Integer的数值存储问题
1 public boolean chkPalindrome(ListNode A) { 2 ArrayList<Integer> list = new ArrayList<>(); 3 ListNode cur = A; 4 while(cur != null){ 5 list.add(cur.val); 6 cur = cur.next; 7 } 8 int length = list.size(); 9 int left = 0; 10 int right = length-1; 11 while(left < right){ 12 if(!list.get(left).equals(list.get(right))){ // 此时的值为421 13 return false; 14 } 15 left++; 16 right--; 17 } 18 return true; 19 }
今天在测试上面这段代码时出现了从未见过的一个问题,list.get(left) != list.get(right)竟然为false,明明都是一样的值,在运行时竟然判断为不一样的????后来又用15这个值进行了测试,结果却是true???
今天来讨论一下这个问题~
我们都知道Integer是int的包装类,int所能表示的范围为-2^31~2^31-1,因此Integer所能表示的范围也是一样,但Integer属于包装类,而不是基本类型,所以存在对象的说法。在Integer存在一个缓存池,对于-128到127之间的数,会进行缓存,超过127的整数会new一个Integer的对象,因此将421存入一个Integer类型时,会自动创建一个Integer对象,对象之间值的比较只能使用equals进行比较,不能使用==,==比较的是引用的对象是否一样,而不是对象的值是否一样。而值为1的时候是直接在缓存池中取值,因此用==比较的时候显示为true。
借鉴了别人的博客进行的总结如下:
- Ingeter是int的包装类,int的初值为0,Ingeter的初值为null。
- 无论如何,Integer与new Integer()不会相等。不会经历拆箱过程,i8的引用指向堆,而i4指向专门存放他的内存(常量池),他们的内存地址不一样,使用 == 比较都为false。
- 两个都是非new出来的Integer,使用 == 比较,如果数在-128到127之间,则是true,否则为false
- 两个都是new出来的,==比较都为false。若要比较值是否相等,需使用equals方法进行比较。
- int和Integer(无论new否)对比,都为true,因为会把Integer自动拆箱为int再去比。