如何为在java中为集合数据类型创建的对象计算哈希码?

时间:2016-07-06 14:45:46

标签: java collections hashcode

从最近的研究中,我的理解是 hashCode 是一种方法,它为实例化某种数据类型的对象返回唯一整数。但是计算所有数据类型对象的哈希码将使用相同的算法,还是会根据某些逻辑而变化?我没有获得关于集合数据类型的哈希码计算机制的更多信息。如果有任何澄清或参考将受到高度赞赏。

3 个答案:

答案 0 :(得分:0)

值得一提的是AbstractList如何计算它的hashCode;

/**
 * Returns the hash code value for this list.
 *
 * <p>This implementation uses exactly the code that is used to define the
 * list hash function in the documentation for the {@link List#hashCode}
 * method.
 *
 * @return the hash code value for this list
 */
public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

此外,哈希码不一定是唯一的。

答案 1 :(得分:-1)

计算hashCode取决于班级。没有标准规则。

您只需遵循here解释的规则:

  

hashCode的一般合同是:

     
      
  • 每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。
  •   
  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
  •   
  • 如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。
  •   

答案的这一部分是解释对Qwerky答案的评论,对不起,但要在评论上显示完整的代码片段并不容易。

这是一个简单的代码,解释了为什么 List无法用作地图中的键

    Map<List, String> map = new HashMap<List, String>();
    List list = new ArrayList();
    map.put(list, "a");
    System.out.println("Before: " + map.get(list)); // Print A
    list.add(new Object());
    System.out.println("After: " + map.get(list)); // Print null

请注意,列表遵循hashCode

的合同

正如Brian Goetz和Josh Bloch所指出的那样:

  

如果一个对象的hashCode()值可以根据其状态发生变化,那么在使用这些对象作为基于散列的集合中的键时必须小心,以确保我们不允许它们的状态发生变化被用作哈希键。 所有基于散列的集合都假定对象的散列值在集合中用作键时不会更改。 如果密钥的哈希代码在集合中更改可能会出现一些不可预测且令人困惑的后果。这在实践中通常不是问题 - 通常的做法是使用像List这样的可变对象作为HashMap中的键

答案 2 :(得分:-1)

默认的hashcode方法将对象引用作为classname @ Soome返回数值,这是唯一的,但是在收集的情况下,我们覆盖hashcode方法来生成我们的自定义键,同时我们覆盖equals方法以获取正确的输出。

您可以从我的代码中获取详细信息

package com.rk.collections;

import java.util.HashMap;
import java.util.Map;

class Employee
{
    private String name;
    private int regdno;
    private String city;
   private  String college;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getRegdno() {
    return regdno;
}
public void setRegdno(int regdno) {
    this.regdno = regdno;
}
public String getCity() {
    return city;
}
public void setCity(String city) {
    this.city = city;
}
public String getCollege() {
    return college;
}
public void setCollege(String college) {
    this.college = college;
}
@Override
public int hashCode() {


    return regdno;
}

public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Employee other = (Employee) obj;


    if (regdno != other.regdno)


    return false;
    return true;
}


public String toString() {
    return "Employee [name=" + name + ", regdno=" + regdno + ", city=" + city + ", college=" + college + "]";
}



}

public class MapDemo {
 public static void main(String []args)
 {
     Employee e1=new Employee();
     e1.setName("Amlan");
     e1.setRegdno(326);
     e1.setCity("Bhanjanagar");
     e1.setCollege("IGIT");

     Employee e2=new Employee();
     e2.setName("Amlan");
     e2.setRegdno(325);
     e2.setCity("Sambalpur");
     e2.setCollege("IGIT");

     Employee e3=new Employee();
     e3.setName("Tapas");
     e3.setRegdno(324);
     e3.setCity("Baripada");
     e3.setCollege("IGIT");

     HashMap<Employee,Employee> hs=new HashMap();
     hs.put(e1,e1);
     hs.put(e2,e2);
     hs.put(e3,e3);
     System.out.println(hs.size());
     for(Map.Entry m:hs.entrySet())
     {
         System.out.println(m.getValue());
     }

 }



}