1. HashMap

  标准链地址法实现(下图)。数组方式存储key/value,线程非安全,允许null作为keyvaluekey不可以重复,value允许重复,不保证元素迭代顺序是按照插入时的顺序,keyhash值是先计算keyhashcode值,然后再进行计算,每次容量扩容会重新计算所以keyhash值,会消耗资源,要求key必须重写equalshashcode方法。默认初始容量16,加载因子0.75,扩容为旧容量乘2,查找元素快,如果key一样则比较value,如果value不一样,则按照链表结构存储value。如果需要同步,可以用 CollectionssynchronizedMap方法(Map m = Collections.synchronizedMap(new HashMap(…));)。使HashMap具有同步的能力,或者使用ConcurrentHashMap

  

JDK 1.8之后,加入了static final int TREEIFY_THRESHOLD = 8;,当同一桶内元素个数超过8个,就会将链表结构进行树化。

    /**
* The bin count threshold for using a tree rather than list for a
* bin. Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
*/
static final int TREEIFY_THRESHOLD = 8;

2. HashTable

  线程安全,不允许有null的键和值,线程安全的,它在所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下,它是安全的,但是无疑是效率低下的。

3. ConcurrentHashMap

  HashTable有很多的优化空间,锁住整个table这么粗暴的方法可以变相的柔和点,比如在多线程的环境下,对不同的数据集进行操作时其实根本就不需要去竞争一个锁,因为他们不同hash值,不会因为rehash造成线程不安全,所以互不影响,这就是锁分离技术,将锁的粒度降低,利用多个锁来控制多个小的table,这就是ConcurrentHashMap JDK1.7版本的核心思想。

JDK1.7的实现

在JDK1.7版本中,ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成,如下图所示:

  

  Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,也就是上面的提到的锁分离技术,而每一个Segment元素存储的是HashEntry数组+链表,这个和HashMap的数据存储结构一样

JDK1.8的实现

  JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用SynchronizedCAS来操作,整个看起来就像是优化过且线程安全的HashMap,虽然在JDK1.8中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本。

  

4. TreeMap

  TreeMap实现SortMap接口,基于红黑二叉树的NavigableMap的实现,线程非安全,不允许nullkey不可以重复,value允许重复,存入TreeMap的元素应当实现Comparable接口或者实现Comparator接口,会按照排序后的顺序迭代元素,两个相比较的key不得抛出classCastException。主要用于存入元素的时候对元素进行自动排序,迭代输出的时候就按排序顺序输出

5. LinkedHashMap

  LinkedHashMapHashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。

6. WeakHashMap

  WeakHashMap,从名字可以看出它是某种 Map,允许null作为keyvalue(Both null values and the null key are supported.),非线程安全(this class is not synchronized)。它的特殊之处在于 WeakHashMap 里的entry可能会被GC自动删除,即使程序员没有调用remove()或者clear()方法。

更直观的说,当使用 WeakHashMap 时,即使没有显示的添加或删除任何元素,也可能发生如下情况:

  • 调用两次size()方法返回不同的值;
  • 两次调用isEmpty()方法,第一次返回false,第二次返回true
  • 两次调用containsKey()方法,第一次返回true,第二次返回false,尽管两次使用的是同一个key
  • 两次调用get()方法,第一次返回一个value,第二次返回null,尽管两次使用的是同一个对象。

  WeekHashMap的这个特点特别适用于需要缓存的场景。在缓存场景下,由于内存是有限的,不能缓存所有对象;对象缓存命中可以提高系统效率,但缓存MISS也不会造成错误,因为可以通过计算重新得到。

  要明白WeekHashMap的工作原理,还需要引入一个概念:弱引用(WeakReference)。Java中内存是通过GC自动管理的,GC会在程序运行过程中自动判断哪些对象是可以被回收的,并在合适的时机进行内存释放。GC判断某个对象是否可被回收的依据是,是否有有效的引用指向该对象。如果没有有效引用指向该对象(基本意味着不存在访问该对象的方式),那么该对象就是可回收的。这里的“有效引用”并不包括弱引用。也就是说,虽然弱引用可以用来访问对象,但进行垃圾回收时弱引用并不会被考虑在内,仅有弱引用指向的对象仍然会被GC回收

  WeakHashMap内部是通过弱引用来管理entry的,弱引用的特性对应到WeakHashMap上意味:将一对key, value放入到WeakHashMap里并不能避免该key值被GC回收,除非在WeakHashMap之外还有对该key的强引用

HashMap、HashTable、ConcurrentHashMap、TreeMap、LinkedHashMap、WeakHashMap区别的更多相关文章

  1. Java HashMap、HashTable、TreeMap、WeakHashMap区别

    1.HashMap不是线程安全,而HashTable是线程安全

  2. [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...

  3. 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享.  原文地址: http://blog.csdn.net/zhange ...

  4. HashMap,HashTable,concurrentHashMap,LinkedHashMap 区别

    HashMap 不是线程安全的 HashTable,concurrentHashMap 是线程安全 HashTable 底层是所有方法都加有锁(synchronized) 所以操作起来效率会低 con ...

  5. HashMap 、HashTable、TreeMap、WeakHashMap的区别是什么

    Java为数据结构中的映射定义了一个接口java.util.Map,它有4个实现类:HashTable.HashMap.TreeMap.WeakHashMap. HashMap和HashTable的区 ...

  6. Java集合——HashMap,HashTable,ConcurrentHashMap区别

    Map:“键值”对映射的抽象接口.该映射不包括重复的键,一个键对应一个值. SortedMap:有序的键值对接口,继承Map接口. NavigableMap:继承SortedMap,具有了针对给定搜索 ...

  7. HashSet、HashMap、Hashtable、TreeMap循环、区别

    HashSet 循环 //可以为null HashSet<Object> hashSet =new HashSet<Object>(); hashSet.add(1); has ...

  8. hashmap,hashTable concurrentHashMap 是否为线程安全,区别,如何实现的

    线程安全类 在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的.在jdk1.2之后,就出现许许多多非线程安全的类. 下面是这些线程安全的同步的类: vector:就比arraylist多 ...

  9. Java集合 之Map(HashMap、Hashtable 、TreeMap、WeakHashMap )理解(new)

    HashMap 说明: 在详细介绍HashMap的代码之前,我们需要了解:HashMap就是一个散列表,它是通过“拉链法”解决哈希冲突的.还需要再补充说明的一点是影响HashMap性能的有两个参数:初 ...

  10. Hashtable,HashMap和ConcurrentHashMap的原理及区别

    一.原理 Hashtable 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashM ...

随机推荐

  1. Java并发编程的艺术笔记(九)——FutureTask详解

    FutureTask是一种可以取消的异步的计算任务.它的计算是通过Callable实现的,多用于耗时的计算. 一.FutureTask的三种状态 二.get()和cancel()执行示意 三.使用 一 ...

  2. 191022Django模板

    一.变量和句点符深度查找 字符串变量引用 def show_time(request): now_time = datetime.datetime.now() return render(reques ...

  3. Python学习笔记:第一次接触

    用的是windows的IDLE(python 3) 对象的认识:先创建一个list对象(用方括号) a = ['xieziyang','chenmanru'] a 对list中对象的引用 a[0] # ...

  4. ansible 剧本进阶 角色

    主要内容: playbook(剧本) roles 一.查看收集到的信息 ansible cache -m setup setup (需要了解的参数) ansible_all_ipv4_addresse ...

  5. centos7 搭建测试环境

    1. 下载JDK8 地址:https://download.oracle.com/otn/java/jdk/8u221-b11/230deb18db3e4014bb8e3e8324f81b43/jdk ...

  6. C# 利用AForge.NET开源类库实现 图像素描效果

    引入DLL: using AForge.Imaging; using AForge.Imaging.Filters; //using AForge.Video.DirectShow;可以使用摄像头图像 ...

  7. Cross-Multimedia dataset

    Wikipedia: http://www.svcl.ucsd.edu/projects/crossmodal/ PKU Xmedia: https://github.com/yeqinglee/mv ...

  8. Tensorflow所遇坑

    TensorFlow问题: 1.FLAGS._parse_flags()报错AttributeError:_parse_flags 解决: 因为TensorFlow的版本问题了,TensorFlow版 ...

  9. 使用conda安装命令时一直出现问题,因为从2019年4月添加的国内镜像都不能用了

    安装过程中出现以下问题:(历尽千辛万苦,终于才查到原来是清华源,腾讯源都不能用了)The remote server could not find the noarch directory for t ...

  10. jenkins与docker(DevOps二)

    Jenkins官网 https://jenkins.io/download/ centos 7安装Docker https://www.cnblogs.com/stulzq/p/7743073.htm ...