我有一堂课Odp。我想使用TreeSet来保存Odp对象的有序集合。但是,我一直有问题。
public class OdpStorage {
private TreeSet<Odp> collection = new TreeSet<Odp>();
public addOdp(Odp o) {
return collection.add(o);
}
public int size() {
return collection.size();
}
}
如果它已经在树中,collection.add(Odp o)应该什么也不做,对吧?不知何故,这个单元测试失败了:
OdpStorage ts = new OdpStorage();
Odp ftw = new Odp("LOL");
Odp ktr = new Odp("OMG");
ts.addOdp(ftw);
ts.addOdp(ftw); //should do nothing
ts.addOdp(ftw); //should do nothing
ts.addOdp(ftw); //should do nothing
ts.addOdp(ktr);
assertEquals(2, ts.size());
断言失败。它预计2,但返回值是5.为什么? odp.equals()函数可能搞砸了吗?
同样,调用collection.contains(o)
失败,即使X
集合o.equals(X)
中有一个对象,其中public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Odp))
return false;
Gene other = (Odp) obj;
if (sequence == null) {
if (other.sequence != null)
return false;
} else if (!sequence.equals(other.sequence))
return false;
return true;
}
返回true。
Odp的.equals()函数:(由Eclipse生成)
/**
* this = g0
* if they are equal, g1 is presumed to come first
*
* @return -1 if g0 comes before g1; 1 if g0 comes after g1
*/
@Override
public int compareTo(Odp g1) {
if (sequence.length() < g1.getSeq().length()) {
return -1;
}
else if (sequence.length() > g1.getSeq().length()) {
return 1;
}
if (sequence.compareTo(g1.getSeq()) < 0) {
return -1;
}
return 1;
}
的compareTo:
hashCode()
hashCode()
未被覆盖。问题
更新
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((sequence == null) ? 0 : sequence.hashCode());
return result;
}
如下:
{{1}}
但这仍然无法解决问题。
答案 0 :(得分:3)
您的compareTo
实现永远不会返回0.当对象实例相等时,它应返回0.
答案 1 :(得分:1)
您的collection.add(o)
似乎无法在支持TreeMap
中找到该对象。您的Odp
实施Comparable
或者是否在Comparable
已经实施了TreeSet
方法的compare
上设置了默认compareTo
?如果是这样,您需要确保Comparable
(对于Comparator
)或compare
0
方法如果传入的对象将返回equals
是HashCode()
。
编辑(回复您对原始帖子的评论):
覆盖equals()
时覆盖compareTo
的 EDIT2响应您的g0
实施:
如果g1
和{{1}}相等,则应返回0.这是问题的根源。
答案 2 :(得分:0)
Mate清理你的平等,它有太多的if / elses。用很多条件测试来替换它。如果所有测试都通过,则reutrn true ...是的,它有“goto”语句,但它非常容易阅读,甚至更容易根据需要插入新条件而不需要很多嵌套。嵌套if / elses是邪恶的。使用“elses”是邪恶的,几乎总是不需要。
@Override
public boolean equals(final Object object) {
boolean equals = false;
do {
if (this == object) {
equals = true;
break;
}
if (false == super.equals(object)) {
break;
}
final DocumentView view = Unsafe.cast(object);
if (false == this.document.equals(view.document)) {
break;
}
if (this.revision != view.revision) {
break;
}
if (false == this.user.equals(view.user)) {
break;
}
if (false == this.timestamp.equals(view.timestamp)) {
break;
}
equals = true;
} while (false);
return equals;
}