TreeSet.contains()不会调用重写的equals方法

4
我有一个关于TreeSet的contains()方法的问题。据我所知,contains()应该调用包含对象的equals(),如Java文档所说:
boolean java.util.TreeSet.contains(Object o): 如果此集合包含指定元素,则返回true。 更正式地说,当且仅当此集合包含一个元素e,使得(o==null ? e==null : o.equals(e))时, 返回true。
我的尝试: 我有一组Result Objects的TreeSets,它们都有一个成员变量String baseword。现在我想比较每个TreeSet与所有其他TreeSet,并针对每对共享的basewords创建一个列表。为此,我遍历一次列表以获取treeSet1,并再次遍历以获取treeSet2,然后我遍历treeSet2中的所有ResultObjects,并针对每个运行treeSet1.contains(ResultObject),以查看treeSet1是否包含具有此单词基础的Result Object。我调整了ResultObject的compareTo和equals方法。但似乎我的equals从未被调用过。 有人可以解释一下为什么这不起作用吗?
问候, Daniel
    public static void getIntersection(ArrayList<TreeSet<Result>> list, int value){

          for (TreeSet<Result> treeSet : list){

    //for each treeSet, we iterate again through the list of TreeSet, starting at the TreeSet that is next
                //to the one we got in the outer loop
                for (TreeSet<Result> treeSet2 : list.subList((list.indexOf(treeSet))+1, list.size())){

                //so at this point, we got 2 different TreeSets 
                HashSet<String> intersection = new HashSet<String>();

                for (Result result : treeSet){  
                    //we iterate over each result in the first treeSet and see if the wordbase exists also in the second one                

//!!!
                    if (treeSet2.contains(result)){
                        intersection.add(result.wordbase);
                    }
                }
                if (!intersection.isEmpty()){
                    intersections.add(intersection);
                }
            }
        }


public class Result implements Comparable<Result>{

    public Result(String wordbase, double result[]){
        this.result = result;
        this.wordbase = wordbase;
    }

    public String wordbase;
    public double[] result;

    public int compareTo(DifferenceAnalysisResult o) {

        if (o == null) return 0;

        return this.wordbase.compareTo(o.wordbase);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((wordbase == null) ? 0 : wordbase.hashCode());
        return result;
    }

//never called
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DifferenceAnalysisResult other = (DifferenceAnalysisResult) obj;
        if (wordbase == null) {
            if (other.wordbase != null)
                return false;
        } else if (!wordbase.equals(other.wordbase))
            return false;
        return true;
    }   
}

只有在通过 compareTo 找到树中的正确分支时,才会调用 equals(如果有必要)。 - Thilo
1个回答

12
据我所理解,contains() 应该调用包含对象的 equals() 方法。
但对于 TreeSet,不是这样的。它调用了 compare 方法:
基于 TreeMap 的 NavigableSet 实现。元素使用它们的自然排序或在创建 set 时提供的 Comparator 进行排序,具体取决于使用哪种构造函数。请注意,如果要正确实现 Set 接口,则集合维护的排序(无论是否提供显式比较器)必须与 equals 一致。
你的 compareTo 方法当前与 equals 不一致 - x.compareTo(null) 返回 0,而 x.equals(null) 返回 false。也许你可以接受这个结果,但不应该期望会调用 equals 方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接