1. 程式人生 > >Java Integer比較中的那些坑

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);//可以