这篇“Java中Integer使用的问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中Integer使用的问题怎么解决”文章吧。
很多时候我们写的代码可能是这样的:
Integer num = 127; if(num==128){ //... }
这种情况下,我们拿Integer和一个数字比较的时候,是不会出什么问题。
然后如果我们这样写
Integer num1 = 127; num1++; Integer num2= 128; if (num1 == num2) { System.out.println(true); } else{ System.out.println(false); }
神奇的事情发生了,num1和num2虽然都是128,但是他们并不相等。
这是因为Integer的值如果是-128~127之间的时候,Integer并不会创建新的对象,而是从IntegerCache.cache中取出的,所以他们随便比较都没有问题。
但是如果超出了这个范围,就不一样了。
不信你可以试试下面的代码:
Integer num1 = 127; Integer num2= 127; if (num1 == num2) { System.out.println(true); } else{ System.out.println(false); }
=================================
可惜的是工作中常常忘记了这一点,于是一场意外发生了。
本人前段时间写的一段代码中有下面一段:
String standardItemNameStr = sampleStandardItemList.stream() .filter(item -> item.getSampleId()==sample.getSampleId()) .map(item -> item.getStandardItemName()).collect(Collectors.joining("、"));
系统刚刚上线的时候一切NICE,运行很正常。突然有一天出事了。客户跟反馈出BUG了。
本该显示数据的地方,成了空值。
自己在本地测试,一切OK。代码检测了十遍以上,没发现什么问题。
把生产环境的数据DOWN下来一跑发现其中第二行item.getSampleId()
的值是180,这时突然想起Integer的这个设定。二话不说,修改为下面的代码,一切恢复正常。
String standardItemNameStr = sampleStandardItemList.stream() .filter(item -> item.getSampleId() .equals(sample.getSampleId())) .map(item -> item.getStandardItemName()).collect(Collectors.joining("、"));
这个问题虽然很简单,但还是很容易忽略的。由此也扩展思考了一下,去测试一下Double、Float包装类,并没有catch这类的设计思路。
原因嘛应该也很简单,Integer是整数,很多时候我们用Integer的时候需要用到的值确实是比较小的,所以官方做个catch确实能起到提高执行效率的作用,而且这个缓存命中率还是比较高的,但是小数的主要用途是在小数方面,如果要做catch的话,那数量可就太多了。
那么byte、short、long的包装类会不会也有catch的设计呢?
补充:Java Integer比较中的那些坑
前几天同事偶然遇到的一个问题,在list中查询出重复的值,留下第一个,其余删除。
ArrayList<Integer> a//a中装有要操作的数据,都是数字 for(int i;i<a.size();i++){ //....遍历 for(int j=i;j<a.size();j++){ if(a.get(i)==a.get(j)){ a.remove(j); } } }
然后喜闻乐见的程序出问题了:程序无法将相同的值除第一个外删除掉。说起来这也是一个比较基础性的问题。
int为基本类型,Integer类型为基本包装类型。因而可以将Integer当做一个对象来理解,所以在上面的代码示例中,用==来比较2个对象的引用无疑就是在搞笑了,地址都不一样,怎么可能返回true。
但是这里存在着一些坑,就是Integer有时候用==比较是可以得到true的(值相同),原因如下:
在-128至127之间的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象。
所以推荐都使用equals比较。
附上int类型自动装箱为Integer时的源代码(IntegerCache.low为-128)
public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
这里还牵涉到了一点,就是这里为什么不直接用int类型呢?这是因为ArrayList中只接受Object对象,实际情况如下:
ArrayList al=new ArrayList(); int n=40; Integer nI=new Integer(n); al.add(n);//不可以 al.add(nI);//可以
以上就是关于“Java中Integer使用的问题怎么解决”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。