您的位置:首页 > 其它

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

2016-04-29 18:01 585 查看
最近正在筹备实习的面试,所以在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: