源码分析四(HashMap与HashTable的区别 )
这一节看一下HashMap与HashTable这两个类的区别,工作一段时间的程序员都知道,
hashmap是非线程安全的,而且key值和value值允许为null,而hashtable是非线程安全的,key和
value都不能为null,hashmap类所属方法没有synchronized修饰,源码如下:
获取map集合元素数量:
public int size() {
return size;
}
判断map集合是否为空:
public boolean isEmpty() {
return size == 0;
}
根据key值查询Value,由下面的方法可以看出HashMap类中key可以为空
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
而Hashtable的方法是由synchronized修饰的,所以是线程安全的,源码如下:
获取集合元素数量:
public synchronized int size() {
return count;
}
判断集合是否为空:
public synchronized boolean isEmpty() {
return count == 0;
}
判断是否包含这个元素的值:
public synchronized boolean contains(Object value) {
if (value == null) {
throw new NullPointerException();
}
所以HashMap与Hashtable的第一个区别是Hashmap是非线程安全的,而hashtable是线程安全的。
第二个区别是Hashmap允许key和value的值为空,而hashtable不允许key或者value的值为null
通过如下方法可以看出:
HashMap:key可以为null
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
value可以为空:
public boolean containsValue(Object value) {
if (value == null)
return containsNullValue();
Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
return true;
return false;
}
Hashtable:value不可以为空
public synchronized boolean contains(Object value) {
if (value == null) {
throw new NullPointerException();
}
Entry tab[] = table;
for (int i = tab.length ; i-- > 0 ;) {
for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}
key不能为空,否则会抛空指针异常:
public synchronized V remove(Object key) {
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
V oldValue = e.value;
e.value = null;
return oldValue;
}
}
return null;
}
源码分析四(HashMap与HashTable的区别 )的更多相关文章
- 【集合框架】JDK1.8源码分析之HashMap(一) 转载
[集合框架]JDK1.8源码分析之HashMap(一) 一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化 ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- 【集合框架】JDK1.8源码分析之HashMap(一)
一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也 ...
- 【集合框架】JDK1.8源码分析之HashMap & LinkedHashMap迭代器(三)
一.前言 在遍历HashMap与LinkedHashMap时,我们通常都会使用到迭代器,而HashMap的迭代器与LinkedHashMap迭代器是如何工作的呢?下面我们来一起分析分析. 二.迭代器继 ...
- JDK1.8源码分析之HashMap(一) (转)
一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也 ...
- JDK1.8源码分析之HashMap
一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也 ...
- 【集合框架】JDK1.8源码分析之HashMap
一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也 ...
- ABP源码分析四:Configuration
核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...
- ABP源码分析四十七:ABP中的异常处理
ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...
随机推荐
- Spring Bean装配学习
解释:所谓装配就是把一个类需要的组件给它设置进去,英文就是wire,wiring:注解Autowire也叫自动装配. 目前Spring提供了三种配置方案: 在XML中进行显式的配置 在Java中进行显 ...
- [转] C#开源项目大全
商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7-SDK ...
- OpenSceneGraph-3.2.0 源代码的编辑步骤
到osg官网去下载源代码 官网 再把资源包下载下来叫作3dpart资源包. 源代码下载下来之后依照这个步骤来. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...
- ubuntu16.04安装workbench
sudo dpkg -i mysql-workbench-community-6.3.10-1ubuntu16.04-amd64.deb 报错: Selecting previously unsele ...
- linux下安装redis并配置
redis官网上给出了安装步骤,这里做一下总结. 1.Download, extract and compile Redis with: wget http://download.redis.io/r ...
- 企业私有云部署im,视频服务
1,安全问题 2,员工跨地域 3,内部视频培训 考勤申请,设备借用申请 名片申请 会议室预订 审批 内网,局域网部署 Android源码 https://github.com/starrtc/andr ...
- Bootstrap 里的 popover 被挡住的解决方案
在Bootstarp 中我们可以使用 popover 插件做一些内容的展示, 代码如下: <a data-toggle="popover" data-placement=&q ...
- [技术选型] Node.js
Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低.非常适合小型网站,个性化网站 NodeJS适合运用在高并发.I/O密集.少量 ...
- Sword libcurl使用
libcurl编译 >> ./configure --prefix=/opt/soft/curl --disable-ldap --disable-ldaps >> make ...
- HashMap的最大容量为什么是2的30次方?
今天看HashMap的底层实现,发现HashMap的最大容量规定为: // 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换) static final int MAXIMUM_C ...