1. Java集合中设计了一个接口Java.util.Map,它实现类中hashMaphashTableTreeMapConcurrentHashMapLinkedHashMap
  2. Map类型的集合用来做键值对存储的,也就是key-value形式的。所以不允许键重复,值是可以重复的。

hashMap

  1. hashMap 底层结构是:数组+链表+红黑树(jdk1.8之前就是存储的数组+链表)

    说明:

     数组的特点:查询效率高,插入,删除效率低。
    链表的特点:查询效率低,插入删除效率高。
    在HashMap底层使用数组加(链表+红黑树)的结构完美的解决了数组和链表的问题,使得查询和插入,删除的效率都很高。
    当链表的长度达到某个阀值(8)的时候,这个链表就将转换成红黑树。
    删除的时候可能导致红黑树转换为链表
    扩容也可能导致红黑树转化为链表 扩容有可能导致红黑树拆成两部分, 在这两部分中, 任意部分, 如果元素数量是小于等于6的话, 会由红黑树转化为链表。
    在jdk1.8中,如果链表长度大于8且节点数组长度大于64的时候,就把链表下所有的节点转为红黑树。树形化还有一个要求就是数组长度必须大于等于64,否则继续采用扩容策略
  2. 默认初始容量16, 负载因子0.75,扩容机制是原容量的2倍。且要求容量一定为2的整数次幂

    说明:用数组容量大小乘以负载因子得到一个值,当数组中存储的元素个数超过该值就会调用rehash方法将数组容量增加到原来的两倍。在扩容的时候会生成一个新的数组,原来的所有数据需要重新计算哈希码值重新分配到新的数组,所以扩容的操作非常消耗性能.

  3. 无序的,允许存null(键,值),线程不安全的。可以使用 Collections的synchronizedMap方法保证安全

  4. 存储过程

    说明:存储数据时计算KeyhashCode值%数组的长度得到对应的数组下标,如果这个下标没有值就直接存入,如果有值就会计算euqals()的值是不是相等,相等就覆盖,不相等就往下链。链的太多时会转换为红黑树。

LinkedHashMap

  1. LinkedHashMap是HashMap一个子类,基本完全复用和遵从HashMap的特点
  2. LinkedHashMap在HashMap的基础上维护了一个双向链表,意味着他是有序的。

TreeMap

  1. TreeMap它是基于红黑树的NavigableMap实现。(树中的每个节点的值都会大于或等于它的左子树中的所有节点的值,并且小于或等于它的右子树中的所有节点的值),实现了SortMap接口,能够对保存的记录根据键进行排序。
  2. 不允许NULL(键,值),线程不安全的
  3. 在TreeMap中存储数据时, key-value, 我们可以有两种方式: 一个就是让key本身可以比较(继承Comparable接口实现compareTo) 另一个就是可以在创建TreeMap的时候手动提供一个比较器

HashTable

  1. 无序,线程安全的(几乎所有的方法都加锁),不能存储null值,null键
  2. 底层结构是数组+链表
  3. 默认初始容量11,扩容时2倍+1。且不要求底层数组的容量一定要为2的整数次幂;

ConcurrentHashMap

  1. ConcurrentHashMap 是线程安全的,相比较HashTable,jdk1.8之前ConcurrentHashMap是分段锁(Segment),继承了ReentrantLock。jdk1.8开始线程安全性由synchronized 和 CAS 来保证。
  2. ConcurrentHashMap可以一边更新、一边遍历,也就是说在遍历的时候,ConcurrentHashMap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产生变化。HashTable会抛异常。
  3. get方法没有加锁,remove put是要加锁的。

    说明:jdk1.8之前是分段锁,一般不会出现锁的争抢,jdk1.8开始分的更细了,使用cas机制添加到树的头节点,如果失败了,说明有其他线程在操作,那就再次循环上一步添加操作。如果头节点已经存在了,通过synchronized获得头节点锁,进行后续的操作。

总结

  1. 平常使用HashMap,访问速度快,效率高。
  2. 排序需求的,并且需要自定义排序规则的使用TreeMap。
  3. 线程安全并发的需求时考虑使用ConcurrentHashMap。
  4. 需要快速增删改查而且需要保证遍历和插入顺序一致的存储功能 LinkedHashMap。

补充

  1. 二叉树

    特点:左子节点的值小于父节点,右子节点的值大于父子节点。当有序列表时,会变成链表结构
  2. 平衡二叉树 AVL

    特点:和二叉树唯一不同的就是左子节点和右子节点的高度差最多等于1。
  3. 红黑树

    特点:通过左旋或者右旋维持树的平衡,因为AVL太严格,当树的节点发生变化时会破坏平衡。

hashMap、ConcurrentHashMap、hashTable、TreeMap、LinkedHashMap用法区别详解的更多相关文章

  1. Android——ArrayList 、LinkList、List 区别 & 迭代器iterator的使用 & HashMap、Hashtable、LinkedHashMap、TreeMap

     ArrayList .LinkList.List 区别 & 迭代器iterator的使用 & HashMap.Hashtable.LinkedHashMap.TreeMap 一.几个 ...

  2. Java集合系列(四):HashMap、Hashtable、LinkedHashMap、TreeMap的使用方法及区别

    本篇博客主要讲解Map接口的4个实现类HashMap.Hashtable.LinkedHashMap.TreeMap的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 ...

  3. HashMap、HashTable、LinkedHashMap和TreeMap用法和区别

    Java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap.HashTable.LinkedHashMap和TreeMap.本节实例主要介绍这4中实例的用 ...

  4. 图论中DFS与BFS的区别、用法、详解…

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  5. 图论中DFS与BFS的区别、用法、详解?

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  6. Android中Intent传值与Bundle传值的区别详解

    Android中Intent传值与Bundle传值的区别详解 举个例子我现在要从A界面跳转到B界面或者C界面   这样的话 我就需要写2个Intent如果你还要涉及的传值的话 你的Intent就要写两 ...

  7. [转]ESCAPE()、ENCODEURI()、ENCODEURICOMPONENT()区别详解

    escape().encodeURI().encodeURIComponent()区别详解 JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encode ...

  8. Url解码和编码 escape()、encodeURI()、encodeURIComponent()区别详解

    Server.UrlDecode;解码 Server.UrlEncode;编码 url编码是一种浏览器用来打包表单输入的格式.浏览器从表单中获取所有的name和其中的值 ,将它们以name/value ...

  9. 【转】escape()、encodeURI()、encodeURIComponent()区别详解

    escape().encodeURI().encodeURIComponent()区别详解 原文链接:http://www.cnblogs.com/tylerdonet/p/3483836.html ...

随机推荐

  1. Citus 分布式 PostgreSQL 集群 - SQL Reference(创建和修改分布式表 DDL)

    创建和分布表 要创建分布式表,您需要首先定义表 schema. 为此,您可以使用 CREATE TABLE 语句定义一个表,就像使用常规 PostgreSQL 表一样. CREATE TABLE ht ...

  2. 数据库连接Database link?

    在一个用户下,可以获取到另外的用户下的表的数据,通常在跨数据库时使用. create database link link93 connect to scott identified by tiger ...

  3. JavaScript使用原型链实现继承

    JavaScript实现继承的思想: 一句话总结,让子类的原型等于父类的实例. 详细来说,其实利用了原型的性质即在JavaScript中所有被实例化对象具有相同的原型属性和方法,每一个被实例化对象的原 ...

  4. SpringBoot 自定义配置文件不会自动提示问题

    参阅:https://www.jianshu.com/p/ec3f0b0371e6

  5. Executors 类是什么?

    Executors 为 Executor,ExecutorService,ScheduledExecutorService, ThreadFactory 和 Callable 类提供了一些工具方法. ...

  6. Vue报错之" [Vue warn]: Unknown custom element: <wzwzihello> - did you register the component correctly? For recursive components, make sure to provide the "name" option."

    一.报错截图 [Vue warn]: Unknown custom element: <wzwzihello> - did you register the component corre ...

  7. 什么是arduino及.arduino分类

    关于什么是arduino没有什么可说的,想要接触arduino多多少少的都会对arduino有一定的理解,我认为,arduino应该算是一个连接硬件与软件的平台,通过他,你可以将你的想法以代码的形式呈 ...

  8. 关于小程序websocket全套解决方案,Nginx代理wss

    需求对话 提问 我在本地web能够使用ws协议去链接websocket,但是小程序不能使用. 回答 由于小程序使用的是SSL加密协议,所以需要使用wss.这里wss与ws的关系就相当于https于ht ...

  9. table表格做出圆角效果

    采用border-radius 这个属性的时候在chrome里面没有圆角,倒是在IE里面有圆角. 不知道是不是没有写webkie 前缀,但是加上一段神奇的代码overflow:hidden的是时候在c ...

  10. 一. 为什么要用SpringMVC框架

    以前是怎么做项目的.CoreServlet,起到一个中心处理器作用.所有的请求到服务器,服务器给CoreServlet,在里面处理所有表的增删改查,跳转也在里面做.以前做部门就是 DepServlet ...