同事要對一個集合做過濾,集合中的對象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,不要使用==或者!=