【问题标题】:Hashcodes are appearing different for two user defined objects of same type对于两个相同类型的用户定义对象,哈希码看起来不同
【发布时间】:2017-12-16 15:53:29
【问题描述】:

我有一个程序来搜索键以打印哈希图中的值。但是我对键和值的输入是用户定义的对象。现在当我将输入key 等同于key1 时,为什么程序中对象keykey1 的哈希码看起来不同,尽管返回类型相同,即。 NameInitString str="abc"abc 的哈希码在哪里返回相等?如何在程序中检查keykey1是否相等?我在类型转换为Object 类之后尝试了Objects.equals(key,key1),但仍然没有工作。我已经看到类似的问题,例如[this question][1] 中讨论哈希码相等性的问题,但又该如何做在我的例子中这些对象的相等性。请帮忙。
NameInit

public class NameInit {
String name;
public NameInit(String name)
 {
  this.name = name;
  }
  @Override
  public String toString(){
  return name;
  }    
}

PlaceAndAddInit

public class PlaceAndAddInit {

String place;
int value;
public PlaceAndAddInit(String place,int val) {
   this.place = place;
   this.value= val;
    }
@Override
public String toString(){
  return place+" "+value;
   }
}

主类

public static void main(String[] args) {
  Scanner scan = new Scanner(System.in);
  HashMap h = new HashMap();
  System.out.println("Limit: ");
  int limit = scan.nextInt();
  for(int i=0;i<limit;i++)
    {
     h.put(new NameInit(scan.next()), new PlaceAndAddInit(scan.next(), 
     scan.nextInt()));
    }
  System.out.println("Enter a key to search the value: ");//
  NameInit key= new NameInit(scan.next());//asks for a input from the user to fetch the values
  Set s = h.entrySet();
  Iterator<NameInit> itr = s.iterator();
  while(itr.hasNext())
     {
       Map.Entry<NameInit,PlaceAndAddInit> me = (Map.Entry) itr.next();
       NameInit key1 =me.getKey();
       if(key.equals(key1)){// this never happens with this code as key and key1 holds different hashcodes. So how do I achieve the equality.
           System.out.println(me.getValue());
            }
      }
    }
  }

编辑:我尝试通过equals 方法获得相等性,我发现key1key 的哈希码不同。了解这背后的原因是我提出问题的目的。

【问题讨论】:

  • 不清楚您的确切问题。你应该展示NameInit的实现,至少对于equals()hashCode()

标签: java hashmap hashcode


【解决方案1】:

您没有覆盖hashCode(),因此使用默认值。在默认实现中,keykey1 将具有不同的 hashCode 值,即使您认为它们应该相等,它们也不会相等。所以解决方案是覆盖hashCodeequals 方法,如果您希望能够比较这些对象。

回答你的问题:

编辑:我试图通过 equals 方法获得相等 发现key1和key的hashcode不同。理解 这背后的原因是我的问题的目的。

如果您不提供对equalshashCode 的覆盖,它们将从Object 继承。以下是他们寻找Object的方式:

  public boolean equals(Object obj) {
        return (this == obj);
    }

因此,只有== 的两个对象才会相等,这意味着它们指向完全相同的内存位置。在您的示例中,情况并非如此。 hashCode 是原生的,所以无法显示源代码。

阅读更多内容:

Google search about hashCode and equals

【讨论】:

  • @Override public int hashCode(){ return Objects.hash(name); } public boolean equals(Object o){ NameInit n =(NameInit) o; return Objects.equals(n.name, name); }
【解决方案2】:

Objects.equals 是这样实现的:

return (a == b) || (a != null && a.equals(b));

你看,它基本上是调用aequals方法,不是hashcode方法。无论hashcode 是如何实现的,Objects.equalsa.equals(b) 返回 false 时返回 false。与hashcode方法无关。

所以要解决这个问题,只需重写 equals 方法。这是一个简单的实现:

@Override
public boolean equals(Object obj) {
    return this.hashcode() == obj.hashcode();
}

另外,如果您想在哈希映射中找到键的值,请在哈希映射上调用get 方法,它会在 O(1) 时间内为您完成。不需要这种 O(n) 时间的低效方法。

【讨论】:

    猜你喜欢
    • 2013-04-30
    • 1970-01-01
    • 2013-03-26
    • 2014-01-13
    • 2011-07-23
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多