文档章节

Java面试基础篇——第六篇:常见Map类的区别

developlee的潇洒人生
 developlee的潇洒人生
发布于 07/19 12:02
字数 1048
阅读 36
收藏 7

常见的map类有: HashMap, ConcurrentHashMap (Jdk1.8) , LinkedHashMap, TreeMap, Hashtable。

  1. 其中我们最常用的莫过于HashMap, 和并发情况下使用的ConcurrentHashMap了,它们的主要区别就在于HashMap是非线程安全的,而ConcurrentHashMap是线程安全的。
  2. 并发情况下可以使用HashTable和ConcurrentHashMap ,它们的区别在于:  >* ConcurrentHashMap的hash计算公式:(key.hascode()^ (key.hascode()>>> 16)) & 0x7FFFFFFF, 而 HashTable的hash计算公式:key.hascode() & 0x7FFFFFFF
  • 2.HashTable存储方式都是链表+数组,数组里面放的是当前hash的第一个数据,链表里面放的是hash冲突的数据 ,ConcurrentHashMap是数组+链表+红黑树.
  1. 线程安全的保证: HashTable是在每一个操作方法上都加上synchronized关键字来达到线程安全的目的,而ConcurrentHashMap则是通过CAS算法(CompareAndSwap)来保证线程安全。
  2. ConcurrentHashMap 放弃了分段锁,而使用了Nodo锁,减低了锁的粒度,提高了性能,并使用CAS操作来保证Node操作的原子性。但是ConcurrentHashMap的一些操作使用了synchronized锁,而不是ReentrantLock,虽然说jdk8的synchronized的性能进行了优化,但是我觉得还是使用ReentrantLock锁能更多的提高性能。
  3. 顺序的 Map 实现类:LinkedHashMap,TreeMap

LinkedHashMap 是基于元素进入集合的顺序或者被访问的先后顺序排序,TreeMap 则是基于元素的固有顺序 (由 Comparator 或者 Comparable 确定)。 6. HashMap和Hashtable

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
	...
	}
public class Hashtable<K,V> extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {
	}
  • HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口. 而Dictionary类是一个废弃的类。可想而知,父类被废弃,子类自然也没人用啦~~
  • Hashtable比HashMap多提供了elments() 和contains() 两个方法。 elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。 contains()方法判断该Hashtable是否包含传入的value。它的作用与containsValue()一致。事实上,containsValue() 就只是调用了一下contains() 方法。
  • Hashtable既不支持Null key也不支持Null value。HashMap只支持一个null key ,可以有一个或多个键的值为null.
  • Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步
  • Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽量使用素数、奇数。而HashMap则总是使用2的幂作为哈希表的大小.
  • 计算hash值的方法不同 : Hashtable直接使用对象的hashCode. Hashtable在计算元素的位置时需要进行一次除法运算,而除法运算是比较耗时的。HashMap为了提高计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多。HashMap的效率虽然提高了,但是hash冲突却也增加了。因为它得出的hash值的低位相同的概率比较高.为了解决这个问题,HashMap重新根据hashcode计算hash值后,又对hash值做了一些运算来打散数据。使得取得的位置更加分散,从而减少了hash冲突。当然了,为了高效,HashMap只做了一些简单的位处理。从而不至于把使用2的幂次方带来的效率提升给抵消掉。

© 著作权归作者所有

共有 人打赏支持
developlee的潇洒人生
粉丝 14
博文 17
码字总数 12208
作品 0
杭州
程序员
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
06/21
0
0
Java语言基础+计算机网络+数据结构 知识手册

最近有不少Java同学陆续开始准备找工作,这篇文章算是推给他们让他们提前准备一下。 加油,美好的一天开始啦~ 纯Java语言基础内容 1、常见集合源码分析。(以下是我们被问到过,能想起的所有...

MDove
08/02
0
0
2018年Java编程学习面试最全知识点总结

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰
05/14
0
0
几种Java 枚举查找且不抛异常的实现及其优劣比较

导读 Java Enum是一个非常有用的功能,但很多人通常并不能充分利用,这是因为一些库不会优先择用该功能。通常我们也可以正确使用Java枚举功能,但在许多代码库中往往存在着这样一个问题,于是...

linux-tao
2017/10/24
0
0
[Java 并发编程] 集合框架之 同步容器类 & 并发容器类

吾生也有涯,而知也无涯。———《庄子》 通过上一篇文章,我们已经知道设计一个线程安全类的原则和步骤,以及在设计过程中我们应当注意的细节。实际上,Java 的集合库包含了线程安全集合和非...

seaicelin
05/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

centos7安装redis及开机启动

配置编译环境: sudo yum install gcc-c++ 下载源码: wget http://download.redis.io/releases/redis-3.2.8.tar.gz 解压源码: tar -zxvf redis-3.2.8.tar.gz 进入到解压目录: cd redis-3......

hotsmile
34分钟前
0
0
Confluence 6 数据库和临时目录

数据库 所有的其他数据库,包括有页面,内容都存储在数据库中。如果你安装的 Confluence 是用于评估或者你选择使用的是 Embedded H2 Database 数据库。数据库有关的文件将会存储在 database...

honeymose
48分钟前
1
0
day62-20180820-流利阅读笔记

1.今日导读 2.带着问题听讲解 3.新闻正文(中英文对照) 4.重点词汇 5.拓展内容

aibinxiao
58分钟前
0
0
分布式锁实现及对比

一、问题介绍 日常工作中很多场景下需要用到分布式锁,例如:任务运行(多个节点同一时刻同一个任务只能在一个节点上运行(分片任务除外)),交易接受(前端交易请求发送时,可能由于两次提...

yangjianzhou
今天
3
0
【AI实战】快速掌握TensorFlow(二):计算图、会话

在前面的文章中,我们已经完成了AI基础环境的搭建(见文章:Ubuntu + Anaconda + TensorFlow + GPU + PyCharm搭建AI基础环境),以及初步了解了TensorFlow的特点和基本操作(见文章:快速掌握...

雪饼
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部