2014-05-09 41 views
2

一个HashMap目前,我有这段代码:怎样的hashCode工作在Java

Map<Site, LinkedList<Site.Hosts.Host>> map = new HashMap<Site, LinkedList<Site.Hosts.Host>>(); 

for (PerformanceCounter element : pc) { 
    Site s = new Site(); 

    s.id = Short.parseShort(element.getSite_id()); 
    s.name = element.getSite_name(); 
    s.location = element.getSite_location(); 

    Site.Hosts.Host h = new Site.Hosts.Host(); 
    h.id = Short.parseShort(element.getHost_id()); 

    if (!map.containsKey(s)) { 
    map.put(s, new LinkedList<Site.Hosts.Host>()); 
    } else { 
    map.get(s).add(h); 
    } 
} 

,我读PerformanceCounters名单:

1, C-01, New York, 1001 
1, C-01, New York, 1002 
1, C-01, New York, 1003 

其中101是id, C-01是这个名字,而纽约是这个位置。

不幸的是,我的代码为我的地图创建了3个键值。

我无法使用LinkedList中的3个值生成1个密钥。

我的if(!map.containsKey(s))部分工作不正常,我不知道如何解决这个问题。

+3

HashMap使用hashCode()和equals()来定位和比较键。你忽略了他们吗?你能告诉我们他们的代码吗? –

+0

我没有重写任何方法。我感到困惑的是,我的Site对象有4个字段:Short id,String name,String location和Hosts host。我故意留下“主机”为空,其余的值都是一样的。我不确定是否错误是因为我的比较在对象字段为空时失败。 – user1413969

+3

如果你没有重写equals()和hashCode(),那么Site的2个实例,即使它们的所有字段是相等的,也会不同。阅读Object.equals()和Object.hashCode()的javadoc,确保理解他们做什么和他们的合同是什么,并覆盖它们。另外请注意,使用公共字段是不好的做法,并且使用可变类作为Map键是危险的。 –

回答

4

你是Site.java类的作者。如果是,请确保您有正确的执行方法hashCode()equals()

本合同基本正常工作是:

  1. 如果两个对象是相等的按equals()方法则它们必须有相同的hashCode()
  2. 但是,如果两个对象返回相同的hashCode(),这并不意味着它们会相等。
  3. 此外,如果您使用evaluating hasCode()方法中的任何对象属性,则它们也必须在equals()实现中使用。
+0

我通过在终端中键入xjc从xsd文件生成该类。它相当大,所以我没有发布它,但它没有hashcode或等于overrided。 – user1413969

+0

如果hashcode和equals不存在并且仍然希望用作映射中的键,那么您将不得不添加这两种方法的实现,否则您的映射将无法工作。 – vkg

+1

请参阅[generate-hashCode-and-equals](http://stackoverflow.com/questions/9062539/generating-hashcode-and-equals-when-creating-java-classes-using-mojo-jaxb2-m)讨论一个如何让xjc生成这些的例子。 –