如何为两个对象使用Collections方法(removeAll()和retainAll())

时间:2010-12-16 13:54:33

标签: java list collections apache-commons

我希望在下面得到结果,但实际上并非如此。即使它在我尝试使用String而不是Item Object时也能正常工作。 我想知道为什么原因以及如何编码以获得预期结果。谢谢。

EXPECTED
------------------------------
removed object are:
2
same object are:
1
3
add object are:
4
------------------------------

ACTUAL
------------------------------
removed object are:
1
2
3
same object are:
add object are:
1
3
4
------------------------------

package com.javastudy;

import java.util.ArrayList;
import java.util.List;

public class CollectionCompareToObjects {

 public static void main(String[] args) {

  List<Item> before = new ArrayList<Item>();
  List<Item> after = new ArrayList<Item>();

  before.add(new Item(1L));
  before.add(new Item(2L)); // delete
  before.add(new Item(3L));

  after.add(new Item(1L));
  after.add(new Item(3L));
  after.add(new Item(4L)); // added

  List<Item> removed = new ArrayList<Item>(before);
  removed.removeAll(after);

  System.out.println("removed objects are:");
  for(Item item : removed){
   System.out.println(item.getId());
  }

  List<Item> same = new ArrayList<Item>(before);
  same.retainAll(after);

  System.out.println("same objects are:");
  for(Item item : same){
   System.out.println(item.getId());
  }

  List<Item> added = new ArrayList<Item>(after);
  added.removeAll(before);

  System.out.println("add objects are:");
  for(Item item : added){
   System.out.println(item.getId());
  }

 }

}

package com.javastudy;

public class Item {

 Long id;

 public Item(Long id) {
  this.id = id;
 }

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

}

5 个答案:

答案 0 :(得分:5)

你还没有实现equals()所以你的所有项目都是不同的对象,有些碰巧有一个相同的字段。

你需要实现等于。

我还建议你使用long而不是Long,除非你想要id = null。

答案 1 :(得分:2)

您必须覆盖equals(..)的{​​{1}}方法并比较id字段(基本上,equals方法应该只使用Item进行相应的空值检查。

使用equals和return id.equals(other.getId()) - 两个方法必须始终一起实现,并使用相同的字段。

您需要覆盖这些方法,因为hashCode()removeAll方法通过迭代集合并将现有项目与通过retainAll传递的集合中的项目进行比较来工作p>

答案 2 :(得分:2)

在您的项目类中实施equals()hashCode(),例如像这样:

@Override
public int hashCode(){
    return Objects.hash(id);
}

@Override
public boolean equals(Object obj){
    if(this == obj) return true;
    else if(obj instanceOf Item){ // implicit null check
        Item other = (Item) obj;
        return Objects.equals(this.id, other.id);
    }
    else return false;
}

我猜它会在那之后按预期工作。

答案 3 :(得分:0)

您需要覆盖equals课程的hashCodeItem方法。如果不这样做,则Java使用equals的默认实现,该实现等同于==

Item first = new Item(1);
Item second = new Item(1);
System.out.println(first == second); // Prints false, as expected: they are different objects.
System.out.println(first.equals(second)); // Prints false because of the default equals method.

如果您正确实施equals,则输出将为false,然后是true

答案 4 :(得分:0)

即使使用相同的参数实例化两次Item,也会有2个不同的对象。 两种解决方案:

  • 使用相同的参考
  • 从Object
  • 覆盖等于