Java:TreeSet的问题

时间:2009-10-11 00:56:48

标签: java generics treeset

我有一堂课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}}

但这仍然无法解决问题。

3 个答案:

答案 0 :(得分:3)

您的compareTo实现永远不会返回0.当对象实例相等时,它应返回0.

答案 1 :(得分:1)

您的collection.add(o)似乎无法在支持TreeMap中找到该对象。您的Odp实施Comparable或者是否在Comparable已经实施了TreeSet方法的compare上设置了默认compareTo?如果是这样,您需要确保Comparable(对于Comparator)或compare 0方法如果传入的对象将返回equalsHashCode()

编辑(回复您对原始帖子的评论):

覆盖equals()

时覆盖compareTo

It is recommended

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;
}