equals和==的区别,以及如何将自定义类作为HashMap的Key
2016-04-29 18:01
585 查看
最近正在筹备实习的面试,所以在google了一些和java有关的面试题,虽然这些面试题都有相应的答案,但是如果要真正理解这些答案还是得从阅读java的源代码入手,只有真正看懂了源代码,才能真正的理解这些面试题出现的原因以及才能真正的理解相应的答案!
今天这篇博客虽然题目是如何将一个对象作为HashMap的Key,但是涉及的内容还是比较广泛的,一个是平时面试问的比较多的“==”和“equal”的主要区别是什么,另外一个就是HashMap的Key的提取机制。
在讲解如何将一个对象作为HashMap的Key之前需要掌握一个基本的知识:hashcode
从上面的源码我们可以看出,hashCode方法是默认没有实现的,而且equals方法默认是通过判断两个对象是否是同一个对象(这里也就解释了“==”和“equals”的区别了,在默认情况下,“==”和“equals”的功能是相同的,只有在子类重载了equals方法之后“==”和“equals”才有区别)下面是相应的例子
Employee .java
TestMain.java
输出结果:
true
false
HashMap中Key的提取方式,是利用了对象的HashCode作为key的,具体看下面的源码
HashMap.java
通过上面的程序我们可以看出在hashMap中的key是利用的是对象的hashCode,所以如果我们要将自定义的类作为HashMap的key,那么我们自定义的类只需要实现hashCode()函数就行了,下面是一个简单的例子
Employee.java
输出结果:
10,0
11,1
今天这篇博客虽然题目是如何将一个对象作为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条建议分享:帮助你成为与硅谷工程师一样优秀的程序员
- 如何在Linux中查看所有正在运行的进程
- .NET操作XML文件之泛型集合的序列化与反序列化
- 模板下载
- Android 开发小工具之:Custom Tabs
- HIVE自定义函数之UDF,UDAF和UDTF
- 微信商城开发:本地服务器的环境配置 (内附花生壳内网映射教程)
- Vim全屏配置
- Linux中断处理杂记
- R中模型性能的提升
- HDU 1035 - Robot Motion
- html4向上兼容html5输入框提示placeholder
- 图片里的标志化的构造和执行
- Oracle基础 --常用SQL语句
- 2544hdoj
- maven 子项目引用父项目的变量没有更新
- vs下warning MSB8012解决方案
- libreoffice实现WORD文档转PDF文档
- Android中AndroidManifest.xml中<application>标签的常用元素
- POJ 1679:The Unique MST 次小生成树