2013-03-31 48 views
3

我有兩個java.util.List如下。比較Java中的包裝類型

List<Long> items = new ArrayList<Long>(){{ 
    add(141L); 
    add(142L);   
}}; 

List<Long> itemsExist = new ArrayList<Long>(){{ 
    add(123L); 
    add(124L); 
    add(125L); 
    add(126L); 
    add(127L); 
    add(141L); 
    add(142L);    
}}; 

我試圖刪除的List命名items的元素,如果它們被包含在名爲ItemsExist如下List

Iterator<Long> itemsIterator = items.iterator(); 

while(itemsIterator.hasNext()) 
{ 
    Long item1=itemsIterator.next(); 
    Iterator<Long> itemsExistIterator = itemsExist.iterator(); 

    while(itemsExistIterator.hasNext()) 
    {    
     Long item2=itemsExistIterator.next(); 
     if(item1==item2) 
     { 
      itemsIterator.remove(); 
     } 
    } 
} 

但切除元素(141142)的沒有發生,因爲這種情況下if(item1==item2)這實際上應該是if(item1.equals(item2)),(我可以理解==equals()之間的差異)。


這可以通過一個非常簡單的例子仿效如下。

Long a=new Long(5); 
Long b=new Long(5); 
System.out.println((a==b)+" : "+a.equals(b)); 

這分別返回falsetrue


以下示例返回在兩個比較true

Long a=5L; 
Long b=5L; 
System.out.println((a==b)+" : "+a.equals(b)); 

在這種情況下,既ab似乎是不似乎是與其它實施例的情況下取消裝箱的主題。怎麼樣?

回答

8

這裏是java.lang.Long中的源代碼的一部分:

  private static class LongCache { 
    544   private LongCache(){} 
    545 
    546   static final Long cache[] = new Long[-(-128) + 127 + 1]; 
    547 
    548   static { 
    549    for(int i = 0; i < cache.length; i++) 
    550     cache[i] = new Long(i - 128); 
    551   } 
    552  } 

      public static Long valueOf(long l) { 
    573   final int offset = 128; 
    574   if (l >= -128 && l <= 127) { // will cache 
    575    return LongCache.cache[(int)l + offset]; 
    576   } 
    577   return new Long(l); 
    578  } 

這apears對我來說,龍類維護-128到127之間Long對象的緩存所以a和b你的例子中的變量指向相同的對象Long

+0

令人傷心的反直覺,整數也是如此。 –

1

就像String pool的java維持整數值池在-128至+127。在這個網站上已經有類似的問題了。請參閱Why does the behavior of the Integer constant pool change at 127?

總而言之,如果您將-128到+127範圍內的整數賦值爲文字,它將從整數池中拾取,並且每次使用時都會返回相同的對象相同的文字。

例如,

Integer int1 = 123; 
Integer int2 = 123; // Get the same object from integer pool 
System.out.println(int1.equals(int2)); 
System.out.println(int1== int2); 

上面的代碼可以讓你在這兩種情況屬實。

如果您正在使用new操作創建一個對象,一個新的對象將被創建每次和整數池將不會進入畫面。 例如,

Integer int1 = new Integer(123); 
Integer int2 = new Integer(123); // Gets you a new object 
System.out.println(int1.equals(int2)); 
System.out.println(int1== int2); 

equals方法讓你真實==檢查讓你假的。 你可以在這裏得到更多的見解http://www.devx.com/tips/Tip/42276