[英]Add no duplicates to List of supperclass (check for equality with subclasses)
I have a List<Item> items = new ArrayList<>();
我有一个
List<Item> items = new ArrayList<>();
I add two different Items to, both subclasses of Item
: PortableItem
and SceneryItem
. 我将两个不同的
Item
添加到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());
}
}
Now I would like to detect Items with duplicate ID
s before adding a new one to my List. 现在,我想在将新
ID
添加到列表之前检测ID
的项目。
PortableItem a = new PortableItem("a");
SceneryItem b = new SceneryItem("a");
items.add(a);
items.contains(b);
Returns false. 返回false。 How can I change that behavior?
我该如何改变这种行为?
You could add an equals
method that compared on id, be default an Object
equals another when they are ==
- ie the same instance. 您可以添加一个与id进行比较的
equals
方法,默认情况下,当Object
==
时, Object
等于另一个-即同一实例。 This isn't what you want. 这不是你想要的。
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;
}
}
This is really good practice anyway given your compareTo
method and the requirement that is is consistent with equals - now a.equals(b)
will return true if they have the same id
. 无论如何,给定您的
compareTo
方法和与equals一致的要求,这确实是一个好习惯-现在a.equals(b)
如果具有相同的id
则将返回true。
As you now have an equals
method you have to have a hashCode()
method, again the consistent with equals requirement. 当您现在拥有一个
equals
方法时,您必须具有一个hashCode()
方法,这也是与equals要求一致的方法。
Note that if you override the equals
method in a superclass this obviously won't work unless you use a call to return super.equals
at the end. 请注意,如果您在超类中覆盖
equals
方法,那么除非您使用调用最后return super.equals
,否则这显然将不起作用。
Now, using a List
the contains
method is guaranteed O(n) - this is very slow . 现在,使用
List
可以确保contains
方法O(n)-这非常慢 。 I would recommend using a Set
where contains
is guaranteed O(1). 我建议使用一个
contains
保证为O(1)的Set
。 If you need to maintain order use a LinkedHashSet
or even better a TreeSet
which will use your compareTo
method to order items automagically. 如果您需要维护订单,请使用
LinkedHashSet
或更好的TreeSet
,它将使用您的compareTo
方法自动订购商品。
You can always turn the thing into a List
afterwards with one O(n) call anyway... 无论如何,您总是可以事后通过一个O(n)调用将其转换为
List
。
You need to override the equals()
and hashCode()
methods in the base class to compare by ID. 您需要重写基类中的
equals()
和hashCode()
方法以按ID进行比较。
compareTo()
is only used for sorting. compareTo()
仅用于排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.