TreeSet内部使用TreeMap,因此在使用Treeset时是否需要实现Hashcode方法?

时间:2012-06-13 08:49:47

标签: java collections hashcode treemap treeset

我想知道TreeSet javadocs 所说的含义

  

该类实现了由TreeMap实例支持的Set接口?

在下面的示例中,我没有实现Hashcode方法,但它仍按预期工作,即它能够对对象进行排序。请注意,我故意没有实现一致的Equals实现来检查TreeSet行为。

import java.util.TreeSet;


public class ComparisonLogic implements Comparable<ComparisonLogic>{

String field1;
String field2;

public String toString(){
    return field1+" "+field2;
}

ComparisonLogic(String field1,String field2){
    this.field1= field1;
    this.field2= field2;

}
public boolean equal(Object arg0){
    ComparisonLogic obj = (ComparisonLogic) arg0; 

    if(this.field1.equals(obj.field1))
        return true;
    else
        return false;
}

public int compareTo(ComparisonLogic arg0){
    ComparisonLogic obj = (ComparisonLogic) arg0;   
    return this.field2.compareToIgnoreCase(obj.field2);
}

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    ComparisonLogic x = new ComparisonLogic("Tom", "jon");
    ComparisonLogic y = new ComparisonLogic("Tom", "Ben");
    ComparisonLogic z = new ComparisonLogic("Tom", "Wik");

    TreeSet<ComparisonLogic> set = new TreeSet<ComparisonLogic>();
    set.add(x);
    set.add(y);
    set.add(z);
    System.out.println(set);
}

}

此示例打印[Tom Ben, Tom jon, Tom Wik]。因此,基于compareTo方法进行排序,hashcode()方法在此方案中看起来微不足道。但是,Treeset由TreeMap支持,所以内部如果TreeMap用于排序,TreeMap如何对对象进行哈希处理?

4 个答案:

答案 0 :(得分:7)

我认为你提出了两个问题。

1,为什么您的代码有效?

正如Avithis主题上写的那样:

  

当您不覆盖hashCode()方法时,您的类从Object继承默认的hashCode()方法,该方法为每个对象提供不同的哈希代码。这意味着t1和t2有两个不同的哈希码,即使你要比较它们,它们也是相同的。根据特定的hashmap实现,地图 free 可以单独存储它们。

这意味着它不必单独存储它们,但它可能。试试这段代码:

TreeSet<ComparisonLogic> set = new TreeSet<ComparisonLogic>();
    set.add(new ComparisonLogic("A", "A"));
    set.add(new ComparisonLogic("A", "B"));
    set.add(new ComparisonLogic("A", "C"));
    set.add(new ComparisonLogic("B", "A"));
    set.add(new ComparisonLogic("B", "B"));
    set.add(new ComparisonLogic("B", "C"));
    set.add(new ComparisonLogic("C", "A"));
    set.add(new ComparisonLogic("C", "B"));
    set.add(new ComparisonLogic("C", "C"));
    set.add(new ComparisonLogic("A", "A"));

    System.out.println(set.remove(new ComparisonLogic("A", "A")));
    System.out.println(set.remove(new ComparisonLogic("A", "B")));
    System.out.println(set.remove(new ComparisonLogic("A", "C")));
    System.out.println(set.remove(new ComparisonLogic("B", "A")));
    System.out.println(set.remove(new ComparisonLogic("B", "B")));
    System.out.println(set.remove(new ComparisonLogic("B", "C")));
    System.out.println(set.remove(new ComparisonLogic("C", "A")));
    System.out.println(set.remove(new ComparisonLogic("C", "B")));
    System.out.println(set.remove(new ComparisonLogic("C", "C")));

我的输出如下:

true
true
true
false
false
false
false
false
false

这意味着他们中的一些人不在其中。

2,当Treeset的javadocs说'这个类实现了由TreeMap实例支持的Set接口'时,它意味着什么?

这意味着java 1.7中的TreeSet类如下所示:

public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
{
/**
 * The backing map.
 */
private transient NavigableMap<E,Object> m;

 TreeSet(NavigableMap<E,Object> m) {
    this.m = m;
}

... (lots of other code)     

public boolean contains(Object o) {
    return m.containsKey(o);
}

etc.

这意味着TreeSet类下面有一个映射,并且有很多方法只委托给它。

我希望我能提供帮助。

答案 1 :(得分:1)

TreeSet在内部使用TreeMap确实如此。 TreeMap不需要为关键对象实现hashCode和equals方法。 TreeMap内部使用Red-Black树,这是一种自平衡二叉搜索树。通过使用compareTo方法(关键对象实现Comparable接口)或比较方法(在构造TreeMap时定义比较器,在本例中实际为TreeSet)来维护此树中的顺序。希望它能够清除。

答案 2 :(得分:0)

您的ComparisonObject正在使用hashCode上定义的Object方法。尝试添加许多不同的ComparisonLogic,并为这两个字段添加相同的值,并查看会发生什么。

答案 3 :(得分:0)

TreeSet在内部使用TreeMap对象'm'将对象存储为键值对,这意味着调用

set.add(x);

内部调用TreeMap的put方法:

public boolean add(E e) {
    return m.put(e, PRESENT)==null;
}

现在,如果提供了Comparator,或者在你的情况下使用ComparisonLogic类“compareTo”方法,put方法内部调用compare。

它从不显式使用equals或hashcode而是使用compareTo(Object o1)(在实现Comparable时提供)或compare(Object o1,object o2)(在实现Comparator时提供)方法来确定集合中Object的存在。 / p>

所以要回答你的问题,除非你在比较(compare或compareTo)方法实现中使用它,否则不需要实现hashcode()方法。