I have a List<Item> items = new ArrayList<>();
I add two different Items to, both subclasses of Item
: PortableItem
and 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.
PortableItem a = new PortableItem("a");
SceneryItem b = new SceneryItem("a");
items.add(a);
items.contains(b);
Returns 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. 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
.
As you now have an equals
method you have to have a hashCode()
method, again the consistent with equals requirement.
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.
Now, using a List
the contains
method is guaranteed O(n) - this is very slow . I would recommend using a Set
where contains
is guaranteed O(1). If you need to maintain order use a LinkedHashSet
or even better a TreeSet
which will use your compareTo
method to order items automagically.
You can always turn the thing into a List
afterwards with one O(n) call anyway...
You need to override the equals()
and hashCode()
methods in the base class to compare by ID.
compareTo()
is only used for sorting.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.