hashmap源码学习整理
来源:互联网 发布:高仿香港身份证淘宝 编辑:程序博客网 时间:2024/05/22 09:38
首先从put方法说起(可能有点跳跃),而要说到put方法,就不得不说一下java中判断2个对象相等的方式(因为put方法里要用到),说到这个,那就自然牵扯到2个联系很密切的方法hashcode(),equals()。
这2个方法是在Object类中定义的,我们可以看下官方jdk对它们的定义(一部分):
If two objects are equal according to the {@code equals(Object)} method, then calling the {@code hashCode} method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the{@link java.lang.Object#equals(java.lang.Object)}method, then calling the {@code hashCode} method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
第一段:如果2个对象equals为true,那么他们的hashcode必须返回同样的值。
第二段:如果2个对象equals为false,那么他们的hashcode也可以返回同样的值。
还有这句话:However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.对于不equal的对象返回不同的hashcode值会提高"某些集合类"的性能(就是这些在放入对象到集合时需要判断对象是否相等的集合)
为什么呢?
想象一下,放入1000个对象到hashmap中,如果没有hashcode方法,那么就需要调用1000次equals方法,但是有了hashcode方法,我们可以先判断hashcode相不相等,不相等的话就直接可以判定这2个对象不相等,而这个的前提是建立在你对这个对象的这两个方法的定义:你确保了不相等的对象一定返回不同的hashcode;相等再去调用equals方法比较。(equals方法的性能开销是绝对大于hashcode的)
我们可以看下源码(比较的这一段):
if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
可以看到如果hash值不一样,就不会去计算&& 后面的这个判定方法(即equals方法)
我们可以用代码去验证一下:
class Country {String name;long population;public Country(String name, long population) {this.name = name;this.population = population;}public String getName() {return name;}public void setName(String name) {this.name = name;}public long getPopulation() {return population;}public void setPopulation(long population) {this.population = population;}@Overridepublic int hashCode() {if (this.name.length() % 2 == 0)return 390;elsereturn 950;}@Overridepublic boolean equals(Object obj) {return true;}}public class HashMapStructure {public static void main(String[] args) {Country india = new Country("india", 1000);Country japan = new Country("japan", 10000);System.out.println(india.hashCode());Country france = new Country("france", 2000);Country russia = new Country("russia", 20000);System.out.println(france.hashCode());HashMap<Country, String> countryCapitalMap = new HashMap<Country, String>();countryCapitalMap.put(russia, "Moscow");countryCapitalMap.put(india, "Delhi");countryCapitalMap.put(japan, "Tokyo");countryCapitalMap.put(france, "Paris");System.out.println(countryCapitalMap.size());Iterator<Country> countryCapitalIter = countryCapitalMap.keySet().iterator();while (countryCapitalIter.hasNext()) {Country countryObj = countryCapitalIter.next();String capital = countryCapitalMap.get(countryObj);System.out.println(countryObj.getName() + "----" + capital);}}}
定义了一个country类,name和population2个属性,定义了一个hashmap存放country以及其首都名字。
countryCapitalMap.put(india, "Delhi");countryCapitalMap.put(japan, "Tokyo");
第一个(india)hash到对应地址,填入,第二个(japan)hash到对应地址,显然japan hash计算后返回与india相同的值,产生冲突,所以接下来要判断key是否相等(如果相等,覆盖value,不相等,则就是所谓的哈希冲突,java的解决办法是链地址法,即用一个链表将hash值相等的对象串起来。所以hash函数最后设计的尽量分布,避免产生冲突),显然hashcode相等,再比较equals,当然也是返回true,所以此时覆盖value,india的首都就变成了tokoy。2
russia----Paris
india----Tokyo
put方法就讲到这里。
- hashmap源码学习整理
- HashMap源码要点整理
- HashMap源码学习
- HashMap源码学习
- HashMap源码学习
- HashMap源码学习笔记
- JAVA源码学习-HashMap
- HashMap源码学习
- HashMap源码学习总结
- HashMap源码学习笔记
- HashMap源码学习1
- JDK源码学习之HashMap
- 关于hashMap的源码学习
- 集合学习--HashMap 源码初探
- TreeMap和HashMap源码学习
- [Java]JDK源码学习(3)HashMap
- JDK源码学习系列08----HashMap
- HashMap和HashTable源码学习笔记
- T
- C++流的基础知识
- onActivityResult,startActivityForResult,setResult用法解决从后一个activity带参数跳转到前一个activity且不走前activity的onCre
- 面试技巧总结~
- c语言 根据字符串生成QR二维码 libqrencode库的使用
- hashmap源码学习整理
- jQuery.extend 函数使用详解
- java中自定义对象排序(TreeSet)
- Sublime Text 3 快捷键总结
- C++模板实现快速排序
- MFC保存text文件自动地以当前日期+时间命名文件
- 对于JQ实现网页翻页到底部自动加载的问题
- flex布局
- hdu 1846 Brave Game (巴什博弈)