比较Java中的包装器类型

时间:2013-03-31 16:06:40

标签: java long-integer

我有两个java.util.List如下。

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的{​​{1}}元素,如果它们包含在名为items的{​​{1}}中,如下所示。

List

但删除元素(ItemsExistIterator<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(); } } } )并没有发生,因为141实际应该是142,(我能理解) 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));


以下示例在两次比较中都返回false

true

在这种情况下,trueLong a=5L; Long b=5L; System.out.println((a==b)+" : "+a.equals(b)); 似乎也是取消装箱的主题,而其他示例似乎并非如此。怎么样?

2 个答案:

答案 0 :(得分: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       }

我认为Long类维护的Long个对象的缓存在-128到127之间。因此,示例中的a和b变量指向同一个对象Long

答案 1 :(得分: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