热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

手动HashMap的简单实现

说起HashMap的强大之处,就是其内部使用了哈希算法和链表算法,充分利用好加载因子的强大推动,使得在时间和空间上的成本寻求一种折中,其内部元素在存储和提取不仅可以充分利用好HashMap初始化的空间

说起HashMap的强大之处,就是其内部使用了哈希算法和链表算法,充分利用好加载因子的强大推动,使得在时间和空间上的成本寻求一种折中,其内部元素在存储和提取不仅可以充分利用好HashMap初始化的空间,而且查询效率及其的高!

在面试中,面试官会常问HashMap的底层源码的实现,接下来我简单的手动实现一个HashMap集合:

(一)HashMap中存储的元素类型即为键值对存在,定义一个能包含键值对的内部类:

class MapEntry {
Object key;
Object value;

public MapEntry(Object key, Object value) {
super();
this.key = key;
this.value = value;
}
}

(二)我们使用java.util.LinkedList双向链表来模拟HashMap中底层实现的数组(即链表数组)

/**
* 1.提高查询的效率 2.默认加载因子 (0.75) 即在时间和空间成本上寻求一种折衷。加载因子过大存储空间能得到充分利用,但查询效率会低一点;
* 加载因子过小,存储空间利用率降低,但是查询速度会高一点!(加载因子的设计大小要保证存储空间充分利用,且查询效率高)
*/
public class ManualHashMap {

LinkedList[] arr = new LinkedList[999]; // 键值对集合! Map底层结构是:数组 + 链表
int size = 0; // HashMap的容量

// 构造方法
public ManualHashMap() {
}

/*
* 向HashMap中存入键值对
*/
public void put(Object key, Object value) {
MapEntry node = new MapEntry(key, value);
/*
* 获取该键值对在数组中的索引位置(0~998);
* 重写HashCode()方法就是为了让具有相同属性对象具有相同的HashCode值(地址码);
* 由于重写HashCode()方法在任何种程度上,都会出现一定的Bug,使得具有不同属性值都会有相同的HashCode码值;
* 此时就需要重写equals()方法,进行二次比较key值是否相同,就可做到万无一失了!
*/
int hash = node.key.hashCode() % arr.length;
hash = hash <0 ? -hash : hash;
if (arr[hash] == null) { // 此索引位置为空
LinkedList list = new LinkedList<>();//创建一个双向链表
arr[hash] = list;
list.add(node);
size++;
} else { // 该位置有元素
LinkedList list = arr[hash]; // 取出该索引处的链表
// 判断有没有键值重复
boolean flag = false;//判断此链表中,是否存在重复的键值
for (int i = 0; i MapEntry temp = (MapEntry) list.get(i);
if (temp.key.equals(key)) { // 键值有重复
temp.value = value; // value值覆盖
flag = true;
}
}
if(!flag){//不存在重复的key,需添加此元素
list.add(node);
size++;
}
}
}

/*
* 获取键值对中某个键值对对象
*/
public Object get(Object key) {
int hash = key.hashCode() % arr.length;
hash = hash <0 ? -hash : hash;
if (arr[hash] != null) {
LinkedList list = arr[hash];
for (int i = 0; i MapEntry temp = (MapEntry) list.get(i);
if(temp.key.equals(key)){
return temp.value;
}
}
}
return null;
}

public static void main(String[] args) {
ManualHashMap map = new ManualHashMap();
map.put("6", "b");
map.put("6", "a");
map.put("5", "c");
map.put("4", "d");
System.out.println(map.size);//3
System.out.println(map.get("6"));//a
}
}
本人只是简单的实现了HashMap存取数据的详细过程,加载因子以及数组的扩容再次赋值,过于繁琐,若需理解深透,请自行查阅HashMap底层的源代码!


推荐阅读
  • 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每 ... [详细]
  • 本篇文章给大家分享的是有关Java中怎么对HashMap按键值排序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • HashTable与ConcurrentHashMap均可实现HashMap的功能,对外提供了键值对存储的数据结构。但是在内部结构及实现上有何区别,性能上的差异到底在哪里又是如何导致的 ... [详细]
  • 转载自:http:www.blogjava.netCarpenterLeearchive20160427430268.html总体介绍之所以把HashSet和HashMa ... [详细]
  • 将学生对象和学生的归属地通过键与值存储到map集合中。importjava.util.HashMap;importjava.util.Iterator;importjava.uti ... [详细]
  • 01Map集合概述A:Map集合概述:我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同a:Collection中的集合 ... [详细]
  • Java面试 HashMap、HashSet源码解析
    本章所有源代码基于JDK1.8版本HashMap和HashSet是JavaCollectionFramework的两个重要成员,其中HashMap是Map接口的常用实现类,Hash ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 我有3个来自RESEARCHS的映射值,指定要使用参考数据集填充的行中的范围。该研究 ... [详细]
  • 手写HashMap,快手面试官直呼内行
    手写HashMap,快手面试官直呼内行-手写HashMap?这么狠,面试都卷到这种程度了?第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章:这……我当 ... [详细]
  • 写这篇文章起源于一道面试题,如何将自定义的类对象作为key存储到HashMap中,即考虑怎么判断key的唯一性。首先,我们看以下HashMap中put(…)方法的源码:public ... [详细]
  • hashmap线程不安全允许有null的键和值效率高一点、方法不是Synchronize的要提供外同步有containsvalue和containsKey方法HashMap是Java1 ... [详细]
author-avatar
通天论坛it技术
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有