3

我有两个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);            
}};

我试图删除Listnamed的元素items,如果它们包含在ListnamedItemsExist中,如下所示。

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();
        }
    }
}

但是元素 ( 141and 142) 的删除并没有发生,因为这种情况if(item1==item2)实际上应该是, (我可以理解andif(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));

在这种情况下,两者a和似乎b 都是拆箱的主题,而其他示例似乎并非如此。如何?

4

2 回答 2

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

于 2013-03-31T16:12:30.613 回答
1

就像String pooljava 为 -128 到 +127 范围内的整数值维护一个池一样。这个网站已经回答了一个类似的问题。请参考为什么整数常量池的行为在 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

于 2013-03-31T16:47:30.020 回答