HashMap、LinkedHashMap、HashTable、HashSet笔记
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笔记相关推荐
- 集合之比较接口器+Map家族的HashMap+LinkedHashMap+Hashtable+ConcurrentHashMap
集合之比较接口器+Map家族的HashMap+LinkedHashMap+Hashtable+ConcurrentHashMap 一.比较器接口 1.内置比较器 – Comparable import ...
- HashMap、HashTable、ConcurrentHashMap、HashSet区别 线程安全类
HashMap专题:HashMap的实现原理--链表散列 HashTable专题:Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析 Hash,Tree数据结构时 ...
- JavaSE学习总结(十四)Map集合/Map和Collection的区别/HashMap/LinkedHashMap/TreeMap/集合间的嵌套/Hashtable/Collections工具类
一.Map集合 我们知道,一个学号就能对应一个学生,并且每个学生的学号都不同,学号就像一个键,对应的学生就是该键对应的值.日常生活中经常能见到这种类似学号对应学生的例子.Java 为了我们更加方便地去 ...
- HashMap和Hashtable及HashSet的区别
Hashtable类 Hashtable继承Map接口,实现一个key-value映射的哈希表.任何非空(non-null)的对象都可作为key或者value. 添加数据使用put(k ...
- java中HashMap,LinkedHashMap,TreeMap,HashTable的区别
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap Map主要用于存储健值对,根 ...
- Hashtable TreeMap HashMap LinkedHashMap的区别
Hashtable TreeMap HashMap LinkedHashMap的区别 Hashtable TreeMap HashMap LinkedHashMap详解 Hashtable 1.内部存 ...
- ArrayList与LinkedList、Vector的区别 HashMap与HashTable、HashSet的区别
一.ArrayList 和 LinkedList区别: (1)两者都是线程不安全,都实现了Collection接口. (2)数据结构:ArrayList是基于动态数组的数据结构,LinkedList是 ...
- JAVA复习5(集合——集合的遍历 Iteratorforeach、Enumeration——HashMap、HashTable、LinkedHashMap——map的遍历)
集合的遍历 Iterator foreach 掌握 Enumeration List Set 观察两个接口 迭代器输出 Iterator Set接口 或者 List 接口 都存在 ...
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
Hash算法 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的 ...
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)
HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...
最新文章
- 让数据库变快的10个建议
- 转载:VMware workstation创建虚拟机,安装Ubuntu系统
- 锦州中学高考2021成绩查询,锦州高中成绩排名2021,锦州中考分数线排行榜
- [转]JavaScript构造函数及原型对象
- 各种快速幂(qaq)
- Springboot事务处理
- leetcode 移动零
- python 图片拼接成固定行列
- Struts2的声明式异常处理
- gnu grub version 2.0.2设置启动顺序_如何修复grub异常
- 使用python实现一个(文件版)简单的课程管理系统
- excel导入自定义单元格式yyyymd hmmss时间方法
- C4D学习笔记1-动画-动画关键帧
- 重新回归最初始的51单片机,跟我一起学单片机吧(内含单片机驱动、烧录软件、程序开发软件的安装和使用)
- wh计算公式_功率计算公式
- 该虚拟机似乎正在使用中。如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权
- 【线程状态、等待与唤醒、Lambda表达式、Stream流】
- RabbitMQ快速入门(详细)
- 钢七连实战教学 老师和学生的差别
- Python之人民币与美元的换算
热门文章
- Atiitt 关于不可替代性的思索 目录 1.1. 不可替代性与 这份工作谁都能干无关	1 1.2. 不可替代性未必很好,因为其岗位可能很累或者收入很低	1 1.3. 不可替代性与报酬无关	1 2
- Atitit 提升战力眼光和组织能力的几大要点 目录 1. 成长金字塔模型 德雷福斯模型	1 2. 提升战略眼光,	3 2.1. 视野与格局	3 2.2. 未来预测 未来发展负责,判断未来趋势,	3
- Atitit Persistence API持久性标准化法总结 目录 1. 持久性对于大多数企业应用程序都非常要害	1 2. 持久化api内容	2 2.1. 一种声明式地执行O-R映射的方式。	2
- Atitit webshell选型 1. PHP Shell 2.4	1 1.1. 设置密码	4 2. 测试切换目录	4 2.1. 自己实现	5 1.PHP Shell 2.4 Please co
- Atitit.设计模式-----触发器模式 trigger 详解
- paip.js input onclick失灵不起作用无反应的解决.txt
- paip.silverlight设计器载入异常NullReferenceException问题。
- 盘点国内外私募基金业绩报酬计提方式
- Rust : CTP 中异步处理
- python : autopep8