HashMap

HashMap存储的是:键值对 (key, value)

HashMap的Key可以冲突,在冲突时,覆盖原有的Key对应的Value值。
下面是一个Key冲突的例子,运行效果如下:

目标位置相同时,节点形成链表。如下

代码(一共三个版本,最终版在最下面)

  • 版本一:put方法

MyHashMap.java

package cn.hanquan.file;public class MyHashMap {Node[] table;// 位桶数组int size;// 存放键值对的个数public MyHashMap() {table = new Node[16];}public void put(Object key, Object value) {// 定义新节点对象Node newNode = new Node();newNode.hash = myHash(key.hashCode(), table.length);newNode.key = key;newNode.value = value;newNode.next = null;Node temp = table[newNode.hash];// 用来检查位置是否被占用Node last = null;// 临时存储上一个节点if (temp == null) {// 未占用table[newNode.hash] = newNode;} else {// 被占用while (temp != null) {if (temp.key.equals(key)) {// 重复System.out.println("key重复: key=" + key + ",value=" + value);temp.value = value;// 覆盖value, 而hash, key, next保持不变return;} else {// 不重复last = temp;// 小弟踩着大哥脚印temp = temp.next;// 大哥先走一步}}last.next = newNode;}}public static void main(String[] args) {MyHashMap h = new MyHashMap();System.out.println("长度:" + h.table.length);h.put(10, "aa");h.put(20, "bb");h.put(30, "cc");h.put(20, "ssss");System.out.println("执行完毕");}// 计算放入那个桶public int myHash(int v, int length) {System.out.println("hash=" + (v % length));return v % length;}
}

Node.java

package cn.hanquan.file;public class Node {int hash;Object key;Object value;Node next;
}

  • 版本二:添加 toString 方法

Node.java

package cn.hanquan.file;public class Node {int hash;Object key;Object value;Node next;
}

MyHashMap.java

package cn.hanquan.file;/** 实现put方法,增加一个元素* 实现toString方法,仿版查看map中的键值对信息*/
public class MyHashMap {Node[] table;// 位桶数组int size;// 存放键值对的个数public MyHashMap() {table = new Node[16];}public void put(Object key, Object value) {// 定义新节点对象Node newNode = new Node();newNode.hash = myHash(key.hashCode(), table.length);// System.out.println("key=" + key + "hashCode=" + key.hashCode());newNode.key = key;newNode.value = value;newNode.next = null;Node temp = table[newNode.hash];// 用来检查位置是否被占用Node last = null;// 临时存储上一个节点if (temp == null) {// 未占用table[newNode.hash] = newNode;} else {// 被占用while (temp != null) {if (temp.key.equals(key)) {// 重复System.out.println("key重复: key=" + key + ",value=" + value);temp.value = value;// 覆盖value, 而hash, key, next保持不变return;} else {// 不重复last = temp;// 小弟踩着大哥脚印temp = temp.next;// 大哥先走一步}}last.next = newNode;}}public String toString() {StringBuilder sb = new StringBuilder("{");for (int i = 0; i < table.length; i++) {Node temp = table[i];while (temp != null) {// 遍历链表sb.append("[" + i + "]" + temp.key + "->" + temp.value + ",");// 不纠结最后多余的逗号,后面直接替换成}就行temp = temp.next;}}sb.setCharAt(sb.length() - 1, '}');return sb.toString();}public static void main(String[] args) {MyHashMap h = new MyHashMap();System.out.println("长度:" + h.table.length);h.put(10, "aa");System.out.println(h.toString());h.put(20, "bb");System.out.println(h.toString());h.put(30, "cc");System.out.println(h.toString());h.put(20, "dd");System.out.println(h.toString());h.put(53, "ee");System.out.println(h.toString());h.put(69, "ff");System.out.println(h.toString());h.put(85, "gg");System.out.println(h.toString());}// 计算放入那个桶public int myHash(int v, int length) {// System.out.println("hash=" + (v % length));return v % length;}
}

运行结果

长度:16
{[10]10->aa}
{[4]20->bb,[10]10->aa}
{[4]20->bb,[10]10->aa,[14]30->cc}
key重复: key=20,value=dd
{[4]20->dd,[10]10->aa,[14]30->cc}
{[4]20->dd,[5]53->ee,[10]10->aa,[14]30->cc}
{[4]20->dd,[5]53->ee,[5]69->ff,[10]10->aa,[14]30->cc}
{[4]20->dd,[5]53->ee,[5]69->ff,[5]85->gg,[10]10->aa,[14]30->cc}


  • 版本三:增加 get 方法

Node.java

package cn.hanquan.file;public class Node {int hash;Object key;Object value;Node next;
}

MyHashMap.java

package cn.hanquan.file;/** 实现put方法,增加一个元素* 实现toString方法,仿版查看map中的键值对信息* 实现get方法,通过键对象查找相对应的值对象*/
public class MyHashMap {Node[] table;// 位桶数组int size;// 存放键值对的个数public MyHashMap() {table = new Node[16];}public void put(Object key, Object value) {// 定义新节点对象Node newNode = new Node();newNode.hash = myHash(key.hashCode(), table.length);// System.out.println("key=" + key + "hashCode=" + key.hashCode());newNode.key = key;newNode.value = value;newNode.next = null;Node temp = table[newNode.hash];// 用来检查位置是否被占用Node last = null;// 临时存储上一个节点if (temp == null) {// 未占用table[newNode.hash] = newNode;size++;} else {// 被占用while (temp != null) {if (temp.key.equals(key)) {// 重复System.out.println("key重复: key=" + key + ",value=" + value);temp.value = value;// 覆盖value, 而hash, key, next保持不变return;} else {// 不重复last = temp;// 小弟踩着大哥脚印temp = temp.next;// 大哥先走一步}}last.next = newNode;size++;}}public String toString() {StringBuilder sb = new StringBuilder("{");for (int i = 0; i < table.length; i++) {Node temp = table[i];while (temp != null) {// 遍历链表sb.append("[" + i + "]" + temp.key + "->" + temp.value + ",");// 不纠结最后多余的逗号,后面直接替换成}就行temp = temp.next;}}sb.setCharAt(sb.length() - 1, '}');return sb.toString();}public Object get(Object key) {int hash = MyHashMap.myHash(key.hashCode(), table.length);Node t = table[hash];while (t != null) {if (key == t.key)return t.value;elset = t.next;}System.out.println("你要查找的key不存在!");return null;}public static void main(String[] args) {MyHashMap h = new MyHashMap();h.put(10, "aa");h.put(20, "bb");h.put(30, "cc");h.put(20, "dd");h.put(53, "ee");h.put(69, "ff");h.put(85, "gg");System.out.println(h.toString());System.out.println(h.get(30));}// 计算放入那个桶public static int myHash(int v, int length) {// System.out.println("hash=" + (v % length));return v % length;}
}

【Java数据结构】自己实现一个HahMap(实现其put, toString, get方法)相关推荐

  1. 【Java 数据结构】实现一个二叉搜索树

    目录 1.认识二叉搜索树 2.实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法 2.4 remove 方法(重点) 3.二叉搜索树总结 1.认识二叉搜索树 ...

  2. java如何写1 6的随机数_随机数的产生方法 关于Java里产生1-6随机数的方法

    11. 在一个双链表中结点p之后插入一个结点s的操作是( ). A. s->right=p只有一条路不能选择--那就是放弃的路:只有一条路不能拒绝--那就是成长的路.有些事,有些人,就应该忘记, ...

  3. Java数据结构——用单链表编写一个简易通讯录

    Java数据结构--用单链表编写一个简易通讯录 1.定义线性表的抽象数据类型(接口) 2.定义单链表的结点Node类 3.定义数据域中的联系人Person类 4.编写顺序表(类) 5.编写测试程序(m ...

  4. java队列_如何彻底搞懂 Java 数据结构?CSDN 博文精选

    作者 | 张振华.Jack 责编 | 郭芮 出品 | CSDN 博客 本文和大家一起来重温<Java数据结构>经典之作. Java数据结构 要理解Java数据结构,必须能清楚何为数据结构? ...

  5. Java 数据结构与算法系列之冒泡排序

    一.前言 相信大部分同学都已经学过数据结构与算法这门课了,并且我们可能都会发现一个现象就是我们所学过的数据结构与算法类的书籍基本都是使用 C 语言来写的,好像没见过使用 Java 写的数据结构与算法. ...

  6. Java数据结构与算法——树(基本概念,很重要)

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 有网友私信我,期待我的下一篇数据结构.非常荣幸文章被认可,也非常感谢你们的监督. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督 ...

  7. java数据结构 队列_Java数据结构与算法[原创]——队列

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本文介绍数据结构中的队列(queue)的概念.存储结构.队列的特点,文末给出ja ...

  8. Java数据结构与算法——插入排序

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本篇文章介绍排序算法中插入排序算法,包括插入排序的思路,适用场景,性能分析,ja ...

  9. Java数据结构和算法:HashMap,哈希表,哈希函数

    1. HashMap概述 HashMap是基于哈希表的Map接口的非同步实现(Hashtable跟HashMap很像,唯一的区别是Hashtalbe中的方法是线程安全的,也就是同步的).此实现提供所有 ...

  10. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

最新文章

  1. java直接打开word_Java
  2. php mod11 10公式,AQL RQL
  3. em在聊天中是什么意思_聊天时,女人总给你发哦、嗯什么意思?这才是高情商的做法...
  4. QT的QOpenGLFunctions类的使用
  5. POJ3197(连分数表示)
  6. C# 运行时通过鼠标拖动改变控件的大小
  7. CSS padding margin border属性讲解
  8. 什么是Git?——Git的学习与使用(一)
  9. linux常用指令(持续更新……)
  10. 《算法设计与分析》黄宇编著 课后习题参考答案
  11. 和程序员男友过节是这样的
  12. 微信小程序自定义组件(1)----地址选择器
  13. java中交换机的作用_交换机链路聚合在网络中的作用
  14. 【b503】篝火晚会
  15. 模块化-CMJESM
  16. 鱼鱼Chen之学写自己的apk(六)ListView带动画图标
  17. 【Audio driver】mixer_paths.xml文件分析
  18. pandas样本分层抽样(可以自己设置每一个类别抽取多少个样本)
  19. C Primer Plus (第六版)编程练习参考答案
  20. 使用Navicat新建PostgreSQL数据库报错ERROR: new collation (en_ US.utf8) is incompatible with the collation of t

热门文章

  1. POJ - 1190 生日蛋糕(dfs+剪枝)
  2. HDU - 3397 Sequence operation(线段树+区间合并)
  3. 机器学习_机器不学习:从Spark MLlib到美图机器学习框架实践
  4. spring mvc原理_Spring常见问题整理
  5. SGU155(笛卡尔树的构造)
  6. 逆向工程核心原理学习笔记(十二):分析abex' crackme #1
  7. 反汇编RETN 0x0c的理解
  8. 【玩转cocos2d-x之三十】点九图和输入框的使用
  9. MAP文件和调试(VC)(从崩溃地址找出错源码位置)
  10. 清晰!我们从来都反对“大中台,小前台”的架构设计!