HashMap底层使用的是数组+单链表的结构,HashMap中存放的键值对(key-value)并且会把他们存储在Map.Entry中,其中Map.Entry中存储的是key的hashcode、value值以及下一个Entry对象的引用next。HashMap实现了Map接口其中最常用的方法就是put(K key,V value)get(Object key)方法,其中put方法的原理是检查key值是否为null,如果为null则将其放入数组的index为0位置。如果当前key不为0,则对该key值取hashCode,并对改hashCode进行位运算,这样做的原因是为了避免哈希碰撞。最后将获取的值hash对数组长度取余数,但是考虑到位位运算的高效性,这里对获取的值hash与数组的长度-1进行&位运算(例如数组的长度是8,那么数组长度-1为7,二进制九尾0111)这样保留的是低位的值。获取到需要插入的值在数组中的index后,如果数组该位置处有值并且该位置的Entry的hash值与被插入的值相同,与此同时key值相同(“==”或者equals相同)那么该位置的value直接替换为将要插入的value值。假如index对应的位置为null或者index对应的位置的Entry不满足hash值相同并且key值相同(“==”或者equals相同)那么直接将被插入的值放入到数组中index位置处,如果该位置有Entry对象,那么作为被插入Entry的next节点向后移动。

get方法也是根据key的hashcode进行位运算然后获取到index,然后遍历该位置的数组和链表值,如果存在Entry的hashcode和该对象的key相同并且与该key相等(“==”或者equals相同),那么返回该值,否则返回null。HashMap允许键值对key-value为null。

HashTable和HashMap实现了Map接口,基于数组+单链表的结构并且存储的也是键值对,其中比较重要的方法也是Map接口中的put方法和get方法。其中HashTable的put方法与HashMap的相同只是HashMap中如果value为null的话就会抛出异常,当key不为null的时候剩余的判断方式与HashMap相同。如果存在hashcode相同并且key值相同(“==”或者equals相同)的情况那么直接替换value值。否则index处添加新的Entry对象并且原有值作为被插入对象的next。与HashMap相比,HashTable不允许键值对key-value为null,因为只要有一个为null就会抛出异常,并且HashTable是线程安全的,查看起public方法可以发现都有synchronize的修饰。

基于以上的理解可以得知HashMap中存入数据是无序的也就是说通过EntrySet的iterator方式打印出的HashMap中的值和put进去的值的顺序不一致。而LinkedHashMap可以做到输入和输出的顺序相同。LinkedHashMap继承了HashMap并实现了Map接口所以其也有put和get方法,并且LinkedHashMap的数据结构也是数组+链表的数据结构,但是LinkeHashMap维护着一个运行于所有条目的双重链接列表,此链接列表定义了迭代顺序,该迭代顺序可以是顺序插入或者访问顺序,默认是按顺序插入排序,如果指定访问顺序后,调用get方法后会将这次访问的元素移至双重连接列表的尾部,不断的访问可以形成按访问顺序排列的链表。LinkedHashMap允许存入key-value均为null,并且键值对也是用Map.Entry来封装,不过增加了两个变量分别是Entry<K,V>before,after表该Entry在双链表中的前一个节点和后一个节点。

LinkedHashMap的put方法和HashMap相同,更具key的hashcode计算出键值对在数组中的index,如果遇到index位置有值并且hashcode和被插入的值相同并且key相同(“==”或者equals相同)那么直接替换value值。如果index的值不满足以上条件那么在相应的位置插入新值,并且双链表中将该值放入尾部,并处理该Entry的after和before的指向。如果该值在双链表中已经存在那么双链表中remove掉之前的值,将该值加到双链表的尾部。如果想按照访问顺序输入LinkedHashMap中的值,那么在构造该对象的时候accessOrder出入true,在进行get方法后,执行上述将Entry对象放入双链表的尾部。如果该值设置为false的话则不执行插入双链表的尾部的逻辑。

HashSet的特点是不允许存入相同的值,其原因是HashSet的底层是一个HashMap,并且HashSet中存入的值是作为HashMap的vaule值,而key是Object对象,所以存入相同的key的时候显示是一样的。

HashMap、LinkedHashMap、HashTable、HashSet笔记相关推荐

  1. 集合之比较接口器+Map家族的HashMap+LinkedHashMap+Hashtable+ConcurrentHashMap

    集合之比较接口器+Map家族的HashMap+LinkedHashMap+Hashtable+ConcurrentHashMap 一.比较器接口 1.内置比较器 – Comparable import ...

  2. HashMap、HashTable、ConcurrentHashMap、HashSet区别 线程安全类

    HashMap专题:HashMap的实现原理--链表散列 HashTable专题:Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析 Hash,Tree数据结构时 ...

  3. JavaSE学习总结(十四)Map集合/Map和Collection的区别/HashMap/LinkedHashMap/TreeMap/集合间的嵌套/Hashtable/Collections工具类

    一.Map集合 我们知道,一个学号就能对应一个学生,并且每个学生的学号都不同,学号就像一个键,对应的学生就是该键对应的值.日常生活中经常能见到这种类似学号对应学生的例子.Java 为了我们更加方便地去 ...

  4. HashMap和Hashtable及HashSet的区别

    Hashtable类     Hashtable继承Map接口,实现一个key-value映射的哈希表.任何非空(non-null)的对象都可作为key或者value.     添加数据使用put(k ...

  5. java中HashMap,LinkedHashMap,TreeMap,HashTable的区别

    java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap Map主要用于存储健值对,根 ...

  6. Hashtable TreeMap HashMap LinkedHashMap的区别

    Hashtable TreeMap HashMap LinkedHashMap的区别 Hashtable TreeMap HashMap LinkedHashMap详解 Hashtable 1.内部存 ...

  7. ArrayList与LinkedList、Vector的区别 HashMap与HashTable、HashSet的区别

    一.ArrayList 和 LinkedList区别: (1)两者都是线程不安全,都实现了Collection接口. (2)数据结构:ArrayList是基于动态数组的数据结构,LinkedList是 ...

  8. JAVA复习5(集合——集合的遍历 Iteratorforeach、Enumeration——HashMap、HashTable、LinkedHashMap——map的遍历)

    集合的遍历 Iterator   foreach  掌握   Enumeration List    Set    观察两个接口 迭代器输出 Iterator Set接口 或者 List 接口 都存在 ...

  9. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    Hash算法 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的 ...

  10. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)

    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...

最新文章

  1. 让数据库变快的10个建议
  2. 转载:VMware workstation创建虚拟机,安装Ubuntu系统
  3. 锦州中学高考2021成绩查询,锦州高中成绩排名2021,锦州中考分数线排行榜
  4. [转]JavaScript构造函数及原型对象
  5. 各种快速幂(qaq)
  6. Springboot事务处理
  7. leetcode 移动零
  8. python 图片拼接成固定行列
  9. Struts2的声明式异常处理
  10. gnu grub version 2.0.2设置启动顺序_如何修复grub异常
  11. 使用python实现一个(文件版)简单的课程管理系统
  12. excel导入自定义单元格式yyyymd hmmss时间方法
  13. C4D学习笔记1-动画-动画关键帧
  14. 重新回归最初始的51单片机,跟我一起学单片机吧(内含单片机驱动、烧录软件、程序开发软件的安装和使用)
  15. wh计算公式_功率计算公式
  16. 该虚拟机似乎正在使用中。如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权
  17. 【线程状态、等待与唤醒、Lambda表达式、Stream流】
  18. RabbitMQ快速入门(详细)
  19. 钢七连实战教学  老师和学生的差别
  20. Python之人民币与美元的换算

热门文章

  1. Atiitt 关于不可替代性的思索 目录 1.1. 不可替代性与 这份工作谁都能干无关 1 1.2. 不可替代性未必很好,因为其岗位可能很累或者收入很低 1 1.3. 不可替代性与报酬无关 1 2
  2. Atitit 提升战力眼光和组织能力的几大要点 目录 1. 成长金字塔模型 德雷福斯模型 1 2. 提升战略眼光, 3 2.1. 视野与格局 3 2.2. 未来预测 未来发展负责,判断未来趋势, 3
  3. Atitit  Persistence API持久性标准化法总结 目录 1. 持久性对于大多数企业应用程序都非常要害 1 2. 持久化api内容 2 2.1. 一种声明式地执行O-R映射的方式。 2
  4. Atitit webshell选型 1. PHP Shell 2.4 1 1.1. 设置密码 4 2. 测试切换目录 4 2.1. 自己实现 5 1.PHP Shell 2.4 Please co
  5. Atitit.设计模式-----触发器模式 trigger  详解
  6. paip.js input onclick失灵不起作用无反应的解决.txt
  7. paip.silverlight设计器载入异常NullReferenceException问题。
  8. 盘点国内外私募基金业绩报酬计提方式
  9. Rust : CTP 中异步处理
  10. python : autopep8