2014-09-06 23 views
2

我正在测试TreeMap的行为并了解排序过程。然而,我仍然困惑的想法是,对于检索,自定义键类需要重写hashCode方法。说了这么多,我已经搜索了足够的谷歌,但找不到任何合理的答案。我们是否需要TreeMap的hashCode实现?

下面是我用过的例子。

class Dog implements Comparable<Dog> { 
    String color; 
    int size; 

Dog(String c, int s) { 
    color = c; 
    size = s; 
} 

int hc; 

@Override 
public int hashCode() { 
    hc = super.hashCode(); 
    return hc; 
} 

@Override 
public int compareTo(Dog o) { 
    return this.color.compareTo(o.color); 
} 
} 

试验规程试验树状图..

public class TestHashMap { 
    public static void main(String[] args) { 
     Dog d1 = new Dog("a", 1); 
     Dog d2 = new Dog("b", 2); 
     Dog d3 = new Dog("c", 3); 
     Dog d4 = new Dog("d", 4); 
     Dog d5 = new Dog("e", 5); 

     Dog d = new Dog("c", 3); 

     TreeMap<Dog, Integer> hm = new TreeMap<>(); 
     hm.put(d1, 10); 
     hm.put(d2, 15); 
     hm.put(d3, 5); 
     hm.put(d4, 20); 
     hm.put(d5, 25); 

     System.out.println("value is :" + hm.get(d)); 
    } 
} 

不管我实现hashCode方法或没有价值的正确检索,但是在调试时,总是hashCode方法被调用,所以我很困惑如果真的hashCode实现是强制性的。

有没有人可以帮助理解从TreeMap检索的正确行为。

请不要从TreeMap复制粘贴java文档。

+2

TreeMap绝对不会调用'hashCode' ---除非你通过调用'TreeMap#hashCode()'强制它。 – 2014-09-06 16:14:43

+1

树不是散列表。没有必要计算哈希值。 – 2014-09-06 16:15:49

+0

请仔细阅读TreeMap的文档。它需要一个实现Comparable接口的类或一个传递给它的构造函数的Comparator。它只调用这些接口的实现 – 2014-09-06 16:16:10

回答

3

hashCode()被称为默认toString()实现的一部分。既然你还没有实现你自己的toString(),我怀疑你在你的代码的某个地方打印了一个Dog,这导致了方法的调用。

+0

打印的'hm.get(d)'是一个Integer ',而不是'狗'。 – NiematojakTomasz 2014-09-06 16:18:49

+0

@Danstahr。 :是的,你是对的我做了同样的错误。 – chaosguru 2014-09-06 16:20:33

+0

@NiematojakTomasz:谢谢你指出这一点。 – Danstahr 2014-09-06 16:30:37

0

我发现这是我的错误,我明确地调用了toString()方法中的hashCode(),它造成了这种混淆。

尽管如此,结论是,对于TreeMap,它遵循可比较接口实现,并且不遵循hashCode和equals实现。

+0

也许你的调试器调用'toString()'和'hashCode()'结果呢?我在IntelliJ的调试中运行你的代码,但是'Dog.hashCode()'中的断点执行永远不会停止。或者,也许你运行不同的代码,比你张贴。 – NiematojakTomasz 2014-09-06 16:29:09

+0

是的发布的代码没有它。这是我的代码,我错过了System.out.println复制。 – chaosguru 2014-09-06 16:32:20

+0

然而,请注意,“强烈建议(尽管不要求)自然顺序与平等一致。这是因为排序集合(和排序映射)没有显式比较器时,它们与自然排序与equals不一致的元素(或键)一起使用时表现得“奇怪”。特别是,这样一个有序的集合(或有序映射)违反了set(或map)的一般契约,它是用equals方法定义的。---并且,每当你重载equals时,你必须*重写'hashCode'来匹配。 – 2014-09-06 16:59:30

相关问题