我有一个List<Item> items = new ArrayList<>();
我将两个不同的项目添加到 Item
的两个子类中:PortableItem
和SceneryItem
.
public class Item implements Comparable<item> {
public String id;
public String desc;
...
public int compareTo(Item o) {
return getId().compareTo(o.getId());
}
}
现在我想检测具有重复 ID
的项目在将新列表添加到我的列表之前。
PortableItem a = new PortableItem("a");
SceneryItem b = new SceneryItem("a");
items.add(a);
items.contains(b);
返回错误。我怎样才能改变这种行为?
最佳答案
您可以添加一个equals
方法来比较id,默认情况下,当它们==
时,一个Object
等于另一个 - 即相同实例。这不是你想要的。
public class Item implements Comparable<Item> {
public String id;
public String desc;
public String getId() {
return id;
}
@Override
public int compareTo(Item o) {
return getId().compareTo(o.getId());
}
@Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + Objects.hashCode(this.id);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Item)) {
return false;
}
final Item other = (Item) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}
}
无论如何,考虑到您的 compareTo
方法以及它的要求与 equals 一致 - 现在 a.equals(b)
如果它们具有相同的id
,则返回 true。
由于您现在有一个 equals
方法,因此您必须有一个 hashCode()
方法,同样符合 equals 要求。
请注意,如果您在父类(super class)中重写了 equals
方法,那么这显然不会起作用,除非您在最后调用 return super.equals
。
现在,使用 List
的 contains
方法可以保证 O(n) - 这非常慢。我建议使用 Set
,其中 contains
保证为 O(1)。如果您需要维护顺序,请使用 LinkedHashSet
甚至更好的 TreeSet
,它将使用您的 compareTo
方法自动对项目进行排序。
之后你总是可以通过一次 O(n) 调用将其转换为 List
...
关于java - 不向 super 类列表添加重复项(检查与子类是否相等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15417492/