发现问题的原因:
在刷LeetCode题进行案例调试时发现:在使用ArrayList集合时,存储的数据类型为Integer。此时程序需要——判断从两个ArrayList对象中取出的两个对象的值,如果相等执行break操作,而调试发现存储值为2时程序正常执行,而存储值为2222222时程序并不能按要求执行?
在Integer类的源码中有着一个静态内部类IntegerCache,该类中的程序的实现导致了以上情况。即在Integer类中存在常量池。该常量池的大小为[-128,127]。当我们赋值的大小在该范围内时将直接从缓存中获取已经创建好的对象,此时所获取的对象地址相同。而超过该范围的对象则是new Integer来创建的此时地址随机分配,因此不相等。而==此时比较的是地址(经过hash算法处理)所以出现的以上情况。
private static class IntegerCache { static final int low = -128; static final int high; static final Integer[] cache; static Integer[] archivedCache; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { h = Math.max(parseInt(integerCacheHighPropValue), 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(h, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; // Load IntegerCache.archivedCache from archive, if possible VM.initializeFromArchive(IntegerCache.class); int size = (high - low) + 1; // Use the archived cache if it exists and is large enough if (archivedCache == null || size > archivedCache.length) { Integer[] c = new Integer[size]; int j = low; for(int i = 0; i < c.length; i++) { c[i] = new Integer(j++); } archivedCache = c; } cache = archivedCache; // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; }
案例:
ArrayList<Integer> a=new ArrayList<>(); ArrayList<Integer> b=new ArrayList<>(); a.add(222); b.add(222); System.out.println(a.get(0)==b.get(0));
结果:false
注:若将两个add方法中的的数值改为[-128,127]之间的数则结果为true。
解决办法:
这里只介绍一种——Integer对象.intValue() 此时返回的就是该Integer对象的值了!
对其他方法感兴趣的朋友可以在CSDN上自行查找!
关于这么做的原因:
缓存经常请求的值可以显著的提高空间与时间性能!