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. 浅析MySQL恶意服务器读取文件原理

    前言 注:本文不涉及对MySQL协议报文研究,仅讲解原理,并且做部分演示. 搭建MySQL恶意服务器读取文件这件事,虽然直接利用门槛较高,但是由于在网上看到了一种比较新颖的利用方式(利用社会工程学引诱 ...

  2. Java 中计算注意!!!

    * 使用BigDecimal需要注意的事项:  * 1.两个BigDecimal值不能使用" +, -, *, / " 进行加减乘除,要使用" add, substrac ...

  3. IO、NIO和AIO的区别

      IO和NIO的区别:其本质就是阻塞和非阻塞的区别. 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,那么久一直等着,知道传输完毕为止.非阻塞概念:应用程序直接可以获取已经准备就绪好的 ...

  4. brew 安装redis

    转:https://www.jianshu.com/p/e1e5717049e8 编辑新安装php的 p.p1 { margin: 0; font: 11px Menlo; color: rgba(0 ...

  5. Spring 应用程序有哪些不同组件?

    Spring 应用一般有以下组件:接口 - 定义功能.Bean 类 - 它包含属性,setter 和 getter 方法,函数等.Spring 面向切面编程(AOP) - 提供面向切面编程的功能.Be ...

  6. 错误问题之“Apache Log4j 漏洞,在版本为包含2.14以内!”

    漏洞概述 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器. Log4j 1.2 中包含一个 SocketServer 类,该类容易受到不可信数据反序列化的影响,当侦听 ...

  7. python学习笔记(一)——Python基础

    一.python 基础语法 python 的解释器在启动时会自动加载一个内建的模块,因此我们在使用 print().input()等函数时不用导入其他模块文件. 基本语法: 每条语句结尾没有分号 定义 ...

  8. printf()函数压栈a++与++a的输出

    printf()中a++与++a的输出问题 在C语言中有个很常用的函数printf(),使用时从右向左压栈,也就是说在printf("%d %d %d %d\n",a,a++,++ ...

  9. 破界!Omi生态omi-mp发布,用小程序开发生成Web

    omi-mp 是什么 Omi 框架是微信支付线研发部和 AlloyTeam 开源的通用 Web 组件化框架,基于 Web Components,用来开发 PC.手机浏览器或者微信.手Q webview ...

  10. React 可视化开发工具 Shadow Widget 非正经入门(之六:markdown)

    本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点.本篇讲解 Markdown 在 Shadow Widget 中的应用. Markdown 在 Shadow Widget 中 ...