同事要对一个集合做过滤,集合中的对象Sku中有两个Integer的属性,一个是商品的真实库存数量stockNum,一个是商品的预占库存occupyNum
要将所有真实库存数量与预占库存数量相等的数据、不相等的数据分别收集起来。
public class Sku {
private Long wareId;
private Integer stockNum;
private Integer occupyNum;
// .....省略
}
public void test(){
List<Sku> skuList = //...省略调用;
List<Sku> equalList = skuList.stream().filter(it -> it.getStockNum() == it.getOccupyNum()).collect(Collectors.toList());
List<Sku> notEqualList = skuList.stream().filter(it -> it.getStockNum() != it.getOccupyNum()).collect(Collectors.toList());
}
问题是当实际库存数量和预占库存数量相等,并且在128以下的都收集到equalList集合里了,但是实际库存数量和预占库存数量同样相等,但是128以上的都收集到notEqualList 集合中去了。按理说都相等行为应该一致呀
原因就是:Interger、Long等基本类型都有常量池,java底层使用的享元模式,就是在-128~127之间创建的Integer都是用的常量池中的同一个值,因此内存地址也是一样的,超过了就是使用的真实的对象做的比较。另外如果不涉及到运算,Integer是不会自动拆箱的,所以使用==或者!=是比较的内存地址。
解决方案:比较对象中的值是否相等请使用equals,不要使用==或者!=