如上图,HashMap是一个链表结构,获取位置下标的时候是通过hash算法来计算下标位置,同时,在存放的值超过整个容量的0.75之后会自动扩容,而且扩容之后需要重新获取entry的next指针,并且在put的时候要进行判断,这个操作是新增还是修改.

首先,定义一个MyMap接口,包含三个方法以及键值对对象:

public interface MyMap<K, V> {// 向集合中插入值public V put( K k, V v );// 根据key获取集合中的值public V get( K k );// 获得集合中元素个数public int size();// 用于获取集合中,键值对的对象interface Entry<K, V> {K getKey();V getValue();V setValue( V value );Entry<K, V> getNext();Entry<K, V> setNext( Entry<K, V> next );}
}

然后,定义MyHashMap继承上方接口,按照HashMap的实现逻辑去一步步实现:

public class MyHashMap<K, V> implements MyMap<K, V> {/*** 根据hash算法,理论上只需要查找一次就能查找到值* Entry 类型数组,默认长度16*/private Entry<K, V>   table[]       = null;// Hashmap的元素个数private int           size;// hashmap集合中的数组的默认长度private static int    defaultLength = 16;// 定义hashmap的加载银子0.75private static double defaltLoad    = 0.75f;@Overridepublic V put( K k, V v ) {if ( table == null ) {table = new Entry[this.defaultLength];}if ( size >= this.defaultLength * this.defaltLoad ) {// 扩容resize();}// 1.分院,确定key/value存放吃的数组的下标位置int index = getIndex( k, this.defaultLength );// 判断是不是修改MyMap.Entry<K, V> entry = table[ index ];while( entry != null ) {if ( entry.getKey().equals( k ) ) {return entry.setValue( v );} else {entry = entry.getNext();}}// 2.创建元素,并且存放在table的index下标上table[ index ] = new Entry<>( k, v, table[ index ] );this.size++;return v;}private void resize() {// 重新散列if ( size >= this.defaultLength * this.defaltLoad ) {System.out.println( "扩容开始..." );Entry<K, V> newTable[] = new Entry[this.defaultLength << 1];MyMap.Entry<K, V> entry = null;for( int i = 0; i < table.length; i++ ) {entry = table[ i ];while( entry != null ) {int index = getIndex( entry.getKey(), newTable.length );MyMap.Entry<K, V> oldEntry = entry.getNext();entry.setNext( newTable[ index ] );newTable[ index ] = (Entry<K, V>) entry;// 继续下一个节点entry = oldEntry;}}table = newTable;this.defaultLength = newTable.length;newTable = null;}}public int getIndex( K k, int length ) {if ( k == null ) {return 0;}int hash = k.hashCode();// 与算法 & 取模return hash & ( length - 1 );}@Overridepublic V get( K k ) {if ( table != null ) {int index = getIndex( k, this.defaultLength );MyMap.Entry<K, V> entry = table[ index ];while( entry != null ) {if ( entry.getKey().equals( k ) ) {return entry.getValue();} else {entry = entry.getNext();}}}return null;}@Overridepublic int size() {return this.size;}// Entrystatic class Entry<K, V> implements MyMap.Entry<K, V> {K                 key;V                 value;MyMap.Entry<K, V> next;public Entry( K key, V value, MyMap.Entry<K, V> next ) {super();this.key = key;this.value = value;this.next = next;}@Overridepublic K getKey() {return this.key;}@Overridepublic V getValue() {// TODO Auto-generated method stubreturn this.value;}@Overridepublic V setValue( V value ) {V oldValue = this.value;this.value = value;return oldValue;}@Overridepublic MyMap.Entry<K, V> getNext() {return this.next;}@Overridepublic MyMap.Entry<K, V> setNext( MyMap.Entry<K, V> next ) {MyMap.Entry<K, V> oldNext = this.next;this.next = next;return oldNext;}}
}

最后,测试:

public class Test {public static void main( String[] args ) {MyHashMap<String, String> map = new MyHashMap<>();map.put( "1号", "打的" );map.put( "2号", "大的" );map.put( "3号", "的的" );map.put( "4号", "改动的" );map.put( "5号", "改个的" );map.put( "6号", "更大的" );map.put( "7号", "发" );map.put( "8号", "发呆" );map.put( "9号", "更大" );map.put( "10号", "更大啊" );map.put( "11号", "啊" );map.put( "12号", "个" );map.put( "13号", "人" );map.put( "14号", "让的" );map.put( "15号", "个的" );map.put( "16号", "发给谁" );map.put( "17号", "但是" );map.put( "18号", "凡事" );map.put( "19号", "给谁" );map.put( "20号", "凡事" );map.put( "21号", "胜多负少" );map.put( "22号", "发顺丰" );map.put( "23号", "凡事的" );map.put( "24号", "凡事发的" );map.put( "25号", "发呆" );map.put( "26号", "佛挡杀佛 " );map.put( "27号", "凡事的" );map.put( "28号", "凡事发多少" );map.put( "29号", "发生的的" );map.put( "30号", "凡事的" );map.put( "31号", "fsfds" );map.put( "32号", "萨芬" );System.out.println( map.get( "17号" ) );}
}

测试结果:扩容开始...
                扩容开始...
                但是

下面我们看看与1.8的差别:

以及数据结构的差别:

至此,我们可以看出两者之间的差别.

jdk1.7的HashMap重写以及与1.8的比较相关推荐

  1. jdk1.8之HashMap

    转载自:http://blog.csdn.net/qq_27093465/article/details/52207135 摘要 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数 ...

  2. JDK1.7和JDK1.8中HashMap是线程不安全的,并发容器ConcurrentHashMap模型

    一.HashMap是线程不安全的 前言 只要是对于集合有一定了解的一定都知道HashMap是线程不安全的,我们应该使用ConcurrentHashMap.但是为什么HashMap是线程不安全的呢,之前 ...

  3. [Java]JDK1.7中HashMap的并发死链

    [Java]JDK1.7中HashMap的并发死链 HashMap的并发死链现象发生在扩容时,在扩容过程中**transfer()**方法负责把旧的键值对转移到新的表中,其代码如下: void tra ...

  4. jdk1.8中HashMap扰动函数及数组长度为什么是2的n次方介绍

    文章目录 前言 一.什么是二进制? 二.计算机采用二进制的原因 三.十进制与二进制相互转换 十进制转成二进制 二进制转换为十进制 与.或.异或运算 按位异或 按位与运算 按位或运算 Jdk1.8中Ha ...

  5. Day1、为什么JDK1.8中HashMap从头插入改成尾插入

    目录 Day1.为什么JDK1.8中HashMap从头插入改成尾插入 存储方式 静态常量 插入元素 扩容 拓展问题 1.为什么JDK1.8采用红黑树存储Hash冲突的元素? 2.为什么在长度小于8时使 ...

  6. java hashmap hash算法,jdk1.8 中 HashMap 的 hash 算法和数组寻址

    开篇 本文基于 jdk1.8 讲述 HashMap 的 hash 算法,但是不会详细介绍其他相关内容(比如用法,底层数据结构).所以必须事先知晓下面几点: HashMap 的底层数据结构是数组,在数组 ...

  7. 详述 JDK1.7 中 HashMap 会发生死链的原因

    文章目录 前置知识 死循环执行步骤1 死循环执行步骤2 死循环执行步骤3 解决方案 总结 前置知识 HashMap死循环是一个比较常见.比较经典的问题,在日常的面试中出现的频率比较高,所以接下来咱们通 ...

  8. 七、JDK1.7中HashMap扩容机制

    导读 前面文章一.深入理解-Java集合初篇 中我们对Java的集合体系进行一个简单的分析介绍,上两篇文章二.Jdk1.7和1.8中HashMap数据结构及源码分析 .三.JDK1.7和1.8Hash ...

  9. JDK1.7中HashMap底层实现原理

    JDK1.7中HashMap底层实现原理 一.数据结构 HashMap中的数据结构是数组+单链表的组合,以键值对(key-value)的形式存储元素的,通过put()和get()方法储存和获取对象. ...

最新文章

  1. 三位数的茎叶图怎么看_霍山石斛哪家好?霍山石斛怎么选择?
  2. mysql 事务sqlserver_MYSQL高级特性 -- 事务处理_sqlserver
  3. 点击下载!《阿里云SRE技术期刊》2021年5月刊发布啦!
  4. leetcode 3. Longest Substring Without Repeating Characters | 3. 无重复字符的最长子串(双指针+滑窗)
  5. 硬核!原型和原型链详解
  6. linux怎样写java代码,linux 怎么写java
  7. 限时福利:入群锁定大会直播+PPT,听百位 AI 技术大咖、20 大热门主题分享!...
  8. amazon aws ip check
  9. 【LeetCode】【数组】题号:*498,对角线遍历
  10. MySQL数据库基础教程(视频)
  11. 20220911- LC第310场周赛
  12. JUCE学习笔记08-合成器(一)振荡器与包络发生器
  13. OpenCV IPLImage常用方法
  14. 用计算机弹怎么会爱上了他,怎么会爱上了他,并决定跟他回家?《纸短情长》...
  15. 通达信交易接口以什么形式执行下单的?
  16. 美赛论文Latex简易模板 | 快速上手(附注释)
  17. easyui ajax方式与后台servlet交互原理
  18. 【PS插件】Retouch4me 10合1一键安装版
  19. 计算机网络基础选择题
  20. LeetCode 344.Reverse String

热门文章

  1. 对话生成:seq2seq模型原理及优化
  2. Feathers: Stage3D加速的UI组件
  3. HTML在线文本编辑器实现原理
  4. Lambda表达式之循环map集合
  5. VMware, RedHat, VirtualBOX, Ubuntu以及Fedora的安装和配置
  6. ATmega8,ATmega16,最小系统板,第一个好评来啦!
  7. mysql添加索引语句_mysql 添加索引语句
  8. 关于cifs协议和samba的应用
  9. PHP: switch结构
  10. 旺旺打标,拼多多打标,淘宝打标,商品标签打标接口