HasMap哈希代码实现

时间:2016-08-09 12:10:14

标签: hashmap

我对哈希码有一些困惑,我试图理解哈希映射如何使用哈希代码和等于方法而我编写了下面的代码,问题是即使我把密钥作为Integer对象,它的使用我在员工对象中覆盖的哈希码方法的哈希码实现(我将其存储为值)。

根据我的理解,因为Key是Integer,它应该使用Object类的哈希码方法而不是我的哈希码实现。

如果这是使用我的哈希代码实现,它应该将密钥视为重复(在我使用employee.getEmpid()时它会这样做)并且不应该存储密钥。

我已经调试了它,流程总是转到我在下面的Employee Class中的哈希码方法的实现。

员工测试

  public class EmployeeTest {

        private static final Map<Integer, Employee> hmap = new HashMap<>();

        public static void main(String[] args) {

            Employee e1 = new Employee(1, "Satya", "IT");
            Employee e2 = new Employee(2, "Deep", "HR");
            Employee e3 = new Employee(1, "Rajeev", "OPERATIONS");
            Employee e4 = new Employee(2, "Lovely", "FINANCE");

            hmap.put(1, e1);
            hmap.put(2, e2);
            hmap.put(3, e3);
            hmap.put(4, e4);

            System.out.println(hmap.put(1, e1).hashCode());
            System.out.println(hmap.put(2, e2).hashCode());
            System.out.println(hmap.put(3, e3).hashCode());
            System.out.println(hmap.put(4, e4).hashCode());

            System.out.println(e1.equals(e3));
            System.out.println(hmap.put(1, e1).equals(hmap.put(3, e3)));
            Set<Entry<Integer, Employee>> hset = hmap.entrySet();

            //Set<String> hashset = hmap.keySet();

            hset.stream().collect(Collectors.toSet()).forEach( e -> System.out.println(e) );

        }
    }

员工

   public class Employee {

        private String empname, empdept;

        private int empid;

        public Employee( int empid, String empname, String empdept )  {

            this.empid = empid;
            this.empname = empname;
            this.empdept = empdept;
        }

        public int hashCode(){

            return this.empid;
        }

        public boolean equals(Employee e){

            return this.empid == e.empid;
        }

        public int getEmpid() {
            return empid;
        }

        public void setEmpid(int empid) {
            this.empid = empid;
        }

        public String getEmpname() {
            return empname;
        }
        public void setEmpname(String empname) {
            this.empname = empname;
        }

        public String getEmpdept() {
            return empdept;
        }

        public void setEmpdept(String empdept) {
            this.empdept = empdept;
        }


    }

输出

1
2
1
2
true
true
1=org.infozech.collection.Map.Employee@1
2=org.infozech.collection.Map.Employee@2
3=org.infozech.collection.Map.Employee@1
4=org.infozech.collection.Map.Employee@2

2 个答案:

答案 0 :(得分:0)

您已在hashcode()课程中以适当的方式覆盖Employee - (它不是一个完美的散列函数(您可以在Effective Java中阅读有关散列的更多信息) )。

当您使用HashMap时,散列用于地图的。这就是您的调试器输入Employee hashcode()方法的原因。

  

如果这是使用我的哈希代码实现,它应该将密钥视为重复(在我使用employee.getEmpid()时它会这样做)并且不应该存储密钥。

为真。如果这两个对象具有相同的哈希码,它们最终会在同一个中,这实际上意味着它们一个接一个地存储在列表中。 HashSet提供与您所描述的功能类似的功能 - 它不允许重复。如果您尝试将两个相等的对象放入HashSet,则只存储一个。

hashcode()equals()是Java编程的非常重要方面。我建议你阅读上面提到的书,或至少this article

答案 1 :(得分:0)

我终于弄清楚了这件事的解释... e1 == e3和e2 == e4具有相同的哈希码,它们分别位于相同的存储桶中。我进入员工哈希代码的原因是,我没有在员工类中覆盖toString(),它没有在内部使用Object类的toString(),而在内部使用员工类的hashcode()来通过System打印它。 out.prinln()。因此,如Piotrek Hryciuk所给出的那样,上面的答案认为对用于存储键的值进行哈希处理是错误的。哈希映射与用于存储到哈希表中的值的哈希码无关。它总是具有密钥的代码。

相关问题