equals和==的区别,以及如何将自定义类作为HashMap的Key

本文深入探讨了Java中“==”与equals的区别,并结合HashMap的工作原理,解析如何自定义类作为其Key,包括hashCode与equals方法的正确实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近正在筹备实习的面试,所以在google了一些和java有关的面试题,虽然这些面试题都有相应的答案,但是如果要真正理解这些答案还是得从阅读java的源代码入手,只有真正看懂了源代码,才能真正的理解这些面试题出现的原因以及才能真正的理解相应的答案!

今天这篇博客虽然题目是如何将一个对象作为HashMap的Key,但是涉及的内容还是比较广泛的,一个是平时面试问的比较多的“==”和“equal”的主要区别是什么,另外一个就是HashMap的Key的提取机制。

在讲解如何将一个对象作为HashMap的Key之前需要掌握一个基本的知识:hashcode

equals()和==的区别

我们知道每一个类都默认继承Object类,当然了也就默认继承了Object类的所有的非private方法和属性,下面是Object的源码的(已经删掉了英文的注释)

public class Object {

    private static native void registerNatives();
    static {
        registerNatives();
    }
    ......
    // HashCode和equals方法是我们主要关注的
    public native int hashCode();
    public boolean equals(Object obj) {
        return (this == obj);
    }
    ......
}

从上面的源码我们可以看出,hashCode方法是默认没有实现的,而且equals方法默认是通过判断两个对象是否是同一个对象(这里也就解释了“==”和“equals”的区别了,在默认情况下,“==”和“equals”的功能是相同的,只有在子类重载了equals方法之后“==”和“equals”才有区别)下面是相应的例子

Employee .java

package mh.test.hash;

public class Employee extends Object{

    private int employeeID;
    public Employee(int employeeID) {
        // TODO Auto-generated constructor stub
        this.employeeID = employeeID;
    }
    // 如果注释掉该方法,下面的TestMain中的所有的输出结果就为false
    // 因为默认的equals方法是两个对象是否相同和"=="效果相同
    public boolean equals(Object anObject) {
        // TODO Auto-generated method stub
        if (this == anObject) {
            return true;
        }
        if(anObject instanceof Employee){
            Employee otherEmployee = (Employee)anObject;
            if(this.employeeID == otherEmployee.employeeID){
                return true;
            }
        }
        return false;
    }
}

TestMain.java

package mh.test.hash;

public class TestMain {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Employee a = new Employee(10);
        Employee b = new Employee(10);
        Employee c = new Employee(11);
        System.out.println(a.equals(b));
        System.out.println(a.equals(c));
    }

}

输出结果:
true
false

如何将自定义类作为HashMap的Key

1. HashMap的key的提取方式

HashMap中Key的提取方式,是利用了对象的HashCode作为key的,具体看下面的源码

HashMap.java

  public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
  }

  static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  }

通过上面的程序我们可以看出在hashMap中的key是利用的是对象的hashCode,所以如果我们要将自定义的类作为HashMap的key,那么我们自定义的类只需要实现hashCode()函数就行了,下面是一个简单的例子
Employee.java

package mh.test.hash;

public class Employee extends Object{

    private int employeeID;
    public Employee(int employeeID) {
        // TODO Auto-generated constructor stub
        this.employeeID = employeeID;
    }
    // HashMap的key值的提取
    public int hashCode() {
        // TODO Auto-generated method stub
        return this.employeeID;
    }

    public boolean equals(Object anObject) {
        // TODO Auto-generated method stub
        if (this == anObject) {
            return true;
        }
        if(anObject instanceof Employee){
            Employee otherEmployee = (Employee)anObject;
            if(this.employeeID == otherEmployee.employeeID){
                return true;
            }
        }
        return false;
    }
    public int getEmployeeID() {
        return employeeID;
    }

    public void setEmployeeID(int employeeID) {
        this.employeeID = employeeID;
    }
}
package mh.test.hash;

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

public class TestMain {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map mymap = new HashMap();
        Employee earray[] = new Employee[3];
        earray[0] = new Employee(10);
        earray[1] = new Employee(11);
        earray[2] = new Employee(10);
        for (int i = 0; i < earray.length; i++) {
            if(!mymap.containsKey(earray[i])){
                mymap.put(earray[i], (Object)String.valueOf(i));
            }
        }

        Iterator entries = mymap.entrySet().iterator();  
        while(entries.hasNext()){
            Map.Entry entry = (Map.Entry) entries.next();  
            Employee key = (Employee) entry.getKey();
            String value = (String) mymap.get(key);
            System.out.println(key.getEmployeeID()+","+value);
        }

    }

}

输出结果:
10,0
11,1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值