如何实现HashMap的顺序存储

从Java API知道,LinkedHashMap继承于HashMap,并且通过双向链表保存各节点的位置信息,实现了顺序存储。但是如果让你自己写一个顺序存储的HashMap,将如何下手呢?从研究LinkedHashMap的源码开始入手,究竟它比HashMap多了哪些东西,让它拥有了顺序存储的能力。

1. 放入元素(put)

从放入一个元素开始,即最常见的V put(K key, V value)方法入手,LinkedHashMap并没有重写HashMap的put方法,但是它重写了最关键的Node<K, V> newNode(int hash, K key, V value, Node next)方法,该方法首先创建一个HashMap.Node的子类LinkedHashMap.Entry,它比Node多了两个指针Entry<K, V> before, after;//用于保存前后两个节点的信息:

LinkedHashMap.Entry<K, V>内部类

其次,把要放入的元素插入双向链表的表尾:

增加元素到双向链表的末尾

注意:LinkedHashMap拥有两个瞬时的属性transient LinkedHashMap.Entry<K,V> tail;//用于保存上一个元素,即表尾;transient LinkedHashMap.Entry<K, V> head;//用于保存第一个元素,即表头。

2. 遍历元素(entrySet)

LinkedHashMap重写了Map接口的Set<Map.Entry<K, V> entrySet()方法,并返回自己的内部类class LinkedEntrySet extends AbstractSet<Map.Entry<K, V>>对象。它使用LinkedEntryIterator迭代器进行遍历,它继承于自己的abstract class LinkedHashIterator抽象类。该迭代器拥有两个Entry的指针next和current,并结合Entry中的before和after指针,实现了LinkedHashMap中元素的顺序遍历。

下面可以看下LinkedHashIterator的nextNode方法的实现:

LinkedHashIterator的nextNode方法

正是nextNode方法使用了LinkedHashMap.Entry<K, V>的after属性,使得iterator的遍历按照放入顺序进行的。

3. 获取元素(get)

LinkedHashMap重写了Map接口的V get(Object key)方法,该方法分两个步骤:1. 调用父类HashMap的getNode(hash(key), key)方法,获取value;2. 如果accessOrder为true(默认为false),那么移动所访问的元素到表尾,并修改head和tail的值:

访问后重排序(accessOrder)

转载来源:https://www.jianshu.com/p/c1e15d673bff

如何实现HashMap的顺序存储相关推荐

  1. 如何实现HashMap顺序存储

    如何实现HashMap顺序存储:可以参考LinkedHashMap的底层实现: 继承HashMap,如 SortHashMap extends HashMap ,然后HashMap里面的每个Node都 ...

  2. hashmap原理_HashMap和HashTable底层原理以及区别

    HashMap底层原理 哈希表:在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1). 数据结构的物理存储结构只有两种:顺序存储结构和 ...

  3. Hash+哈希表+HashMap+HashSet

    Hash+哈希表+HashMap+HashSet 哈希算法,是一类「算法」. 哈希表(Hash Table),是一种「数据结构」. 哈希函数,是支撑哈希表的一类「函数」. Map是映射/地图的意思,在 ...

  4. hashmap containsvalue时间复杂度_面试宝典:数据结构HashMap

    常用数据结构在新增.查找等基础操作上的性能 1.数组 采用一段连续的存储单元来存储数据 对于指定下标的查找,时间复杂度为O(1) 通过给定值进行查找,需要遍历数组,逐一比对给定关键字和数组元素,时间复 ...

  5. java linkedhashmap_java学习-hashMap和linkedHashMap

    1.hashMap和linkedHashMap和treeMap 1 * LinkedHashMap是继承于HashMap,是基于HashMap和双向链表来实现的. 2 * HashMap无序:Link ...

  6. java中的几种泛型类——HashSet、HashMap、TreeSet、TreeMap,遍历map,排序,HashTable比较

    HashSet HashSet<E>泛型类在数据组织上类似于数学上的集合,可以进行"交"."并"."差"等运算. HashSet ...

  7. 深入了解HashMap

    什么是hash? 哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值.哈希值是一段数据唯一且极其紧凑的数值表示形式.如果散列一段明文而且哪怕只更改该段落的一个字母, ...

  8. hashmap是单向链表吗_HashMap源码大剖析

    本文目录哈希表的由来散列技术Map家族子类比较 HashMap与HashTable的区别? ConcurrentHashMap和Hashtable的区别? 同步集合与并发集合? HashMap存储结构 ...

  9. hashmap删除指定key_Java集合之HashMap源码解析(JDK8)

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景非常丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

最新文章

  1. w7怎么查看电脑配置_学室内设计,对电脑配置有何要求?不懂戳这!
  2. php 论坛_推荐一个基于话题的高性能轻型开源PHP论坛程序
  3. 并发编程-03线程安全性之原子性(Atomic包)及原理分析
  4. 二叉树删除节点,(查找二叉树最大值节点)
  5. python部分引入total值的问题_Python数据分析基础与过程综述,关键数据预处理异常点的发现与处理,python,及,流程,回顾,重点,之,值...
  6. appium+Python真机运行测试demo的方法
  7. linux 取出本机IP
  8. php什么是同源策略,javascript - 绕过同源策略的方法
  9. 【HDU5008】Boring String Problem(后缀数组+二分查找+st表)
  10. 马尔科夫随机场 matlab,matlab马尔可夫随机场
  11. 使用openssl实现AES CBC 128 pcks7加密
  12. MySQL全文索引短单词或数字不生效的问题
  13. 网页请求localhost可以,但是请求ip地址就会出现连接超时
  14. 如何下载mysql补丁_如何获取Oracle的补丁通告信息以及下载补丁
  15. GSM/GPRS+GPS模块SIM808
  16. socket通信技术
  17. C语言-printf打印的用法
  18. android如何添加透明图片按钮,如何拥有透明的ImageButton:Android
  19. linux系统可以安装天正吗,Linux上安装Wine运行AutoCAD实例[多图]
  20. 中文Python(1)使用中文Python编程更简单易懂

热门文章

  1. 使用新的 apt 命令在 Ubuntu 16.04 LTS 下管理软件包
  2. iOS中XML解析 (二) libxml2(实例:打印xml内容及存储到数组)
  3. DNS服务器 安装部署 以及子域授权和转发
  4. 数据库设计的6个阶段
  5. 类与对象初识 类是模具 对象是产品 0314 2101
  6. 对象流 ObjectOutputStream java
  7. 单循环 输入一行星花
  8. pyhon-matplotlib包-数据图形化
  9. AWS EC2怎么动态增加磁盘空间
  10. Extjs格式化时间