java - TreeSet内部使用了TreeMap,那么使用Treeset时是否需要实现Hashcode方法呢?

标签 java collections hashcode treemap treeset

我想知道 javadocs for TreeSet

是什么意思

This class implements the Set interface, backed by a TreeMap instance?

在下面的示例中,我没有实现 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 如何对对象进行哈希处理?

最佳答案

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

1,为什么你的代码能正常工作?

作为Avi写在 this主题:

When you don't override the hashCode() method, your class inherits the default hashCode() method from Object, which gives every object a distinct hash code. This means that t1 and t2 have two different hash codes, even though were you to compare them, they would be equal. Depending on the particular hashmap implementation, the map is free to store them separately.

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

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 说“此类实现 Set 接口(interface),由 TreeMap 实例支持”时,这意味着什么?

表示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 类下面有一个 map ,并且有很多方法只委托(delegate)给它。

希望能帮到你。

关于java - TreeSet内部使用了TreeMap,那么使用Treeset时是否需要实现Hashcode方法呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11011291/

相关文章:

Java - 彩票统计解析器

java - 如何删除打印行之间的空间?

c# - 将范围添加到集合

java - 如果我不在 java 中的对象中使用哈希表或哈希集,我是否需要实现 hashcode()

sql - 在postgresql中查找一行的哈希值

java - 为什么值类的值是它的 hashCode "not a good idea"?

java - 如何传递导出的 RMI-IIOP 对象的远程引用

Java 贷款计算器基于用户输入嵌套 for 循环

java - 基于 equals 方法的不同实现来计算列表中项目的频率

java - 在 Hashtable get() 操作中检查 null