特性:

HashMap 与 Hashtable 的分析:

1):HashMap简介

  1、底层数组+链表实现,可以存储null键和null值,线程不安全

  2、HashMap 不是线程安全的

  3、HashMap 是 map 接口的子类。

  4、HashMap 允许null key 和 null value。

  5、允许 key 重复,但是会把之前的覆盖。

  6、HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了Map接口。

  7、HashMap 是 reHash算法,而 HashTable 是 hash算法。两者差不多

  8、HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey。因为contains方法容易让人引起误解。

HashMap结构图:

简单来说,HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(如果不同的key映射到了数组的同一位置处,就将其放入单链表中)。

如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,

仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。

几个比较重要的字段:

//实际存储的key-value键值对的个数
transient int size;
//阈值,当table == {}时,该值为初始容量(初始容量默认为16);当table被填充了,也就是为table分配内存空间后,threshold一般为 capacity*loadFactory。
//HashMap在进行扩容时需要参考threshold,后面会详细谈到
int threshold;
//负载因子,代表了table的填充度有多少,默认是0.75
final float loadFactor;
//用于快速失败,由于HashMap非线程安全,在对HashMap进行迭代时,如果期间其他线程的参与导致HashMap的结构发生变化了(比如put,remove等操作),需要抛出异常ConcurrentModificationException
transient int modCount;

HashMap有4个构造器,其他构造器如果用户没有传入 initialCapacity 和 loadFactor这两个参数,会使用默认值 initialCapacity默认为16,loadFactory默认为0.75

我们看下其中一个:

public HashMap(int initialCapacity, float loadFactor) {
     //此处对传入的初始容量进行校验,最大不能超过MAXIMUM_CAPACITY = 1<<30(230)
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor); this.loadFactor = loadFactor;
threshold = initialCapacity;
     
init();//init方法在HashMap中没有实际实现,不过在其子类如 linkedHashMap中就会有对应实现
}

从上面这段代码我们可以看出,在常规构造器中,没有为数组 table 分配内存空间(有一个入参为指定Map的构造器例外),而是在执行 put 操作的时候才真正构建 table 数组 OK。

接下来我们来看看put操作的实现吧。

public V put(K key, V value) {
//如果table数组为空数组{},进行数组填充(为table分配实际内存空间),入参为threshold,此时threshold为initialCapacity 默认是1<<4(24=16)
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
//如果key为null,存储位置为table[0]或table[0]的冲突链上
if (key == null)
return putForNullKey(value);
int hash = hash(key);//对key的hashcode进一步计算,确保散列均匀
int i = indexFor(hash, table.length);//获取在table中的实际位置
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
//如果该对应数据已存在,执行覆盖操作。用新value替换旧value,并返回旧value
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;//保证并发访问时,若HashMap内部结构发生变化,快速响应失败
addEntry(hash, key, value, i);//新增一个entry
return null;
}

2):HashTable介绍

  1、底层数组+链表实现.

  2、无论 key 还是 value 都不能为 null。

  3、线程安全:实现线程安全的方式是在修改数据时锁住整个HashTable,效率低。

  4、Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题。

  5、hashtable 采用 hash 算法。

 

分享知识-快乐自己:HashMap 与 HashTable 的区别的更多相关文章

  1. java面试题——HashMap和Hashtable 的区别

    一.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Clonea ...

  2. Map集合及与Collection的区别、HashMap和HashTable的区别、Collections、

    特点:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值. Map集合和Collection集合的区别 Map集合:成对出现 (情侣)                       ...

  3. hashMap和hashTable的区别

    每日总结,每天进步一点点 hashMap和hashTable的区别 1.父类:hashMap=>AbstractMap hashTable=>Dictionary 2.性能:hashMap ...

  4. java分享第七天-01(Hashmap和Hashtable的区别&Property)

    一.Hashmap和Hashtable的区别 1 主要:Hashtable线程安全,同步,效率相对低下 HashMap线程不安全,非同步,效率相对高 2 父类:Hashtable是Dictionary ...

  5. HashMap和Hashtable的区别 源码分析

    一:以前只知道HashMap和HashTable区别,死记硬背的记住HashMap 允许key value为空 而Hashtable 不允许为空 HashMap线程是非线程安全的,而Hashtable ...

  6. Java 集合系列 11 hashmap 和 hashtable 的区别

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  7. HashMap与HashTable的区别、HashMap与HashSet的关系

    http://blog.csdn.net/wl_ldy/article/details/5941770 HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是 ...

  8. 面试题·HashMap和Hashtable的区别(转载再整理)

    原文链接: Javarevisited 翻译: ImportNew.com- 唐小娟 译文链接: http://www.importnew.com/7010.html HashMap和Hashtabl ...

  9. java中的hashmap与hashtable的区别

    HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别.主要的区别有:线程安全性,同步(synchronizatio ...

  10. HashMap和Hashtable的区别--List,Set,Map等接口是否都继承自Map接口--Collection和Collections的区别

    面试题: 1.HashMap和Hashtable的区别? HashMap:线程不安全,效率高,键和值都允许null值 Hashtable:线程安全,效率低,键和值都不允许null值 ArrayList ...

随机推荐

  1. Oracle 12c 读书笔记(二):Oracle数据库体系结构

    以11g来分析 数据库实例包括:SGA和一系列后台管理.监控简称 数据库包括三种文件:数据文件.控制文件.重做日志文件 数据库实例和数据库是Orale数据库体系的核心部分 Oracle服务器和实例 实 ...

  2. 关于android编程中service和activity的区别

    一. 绝大部分情况下,Service的作用是用来“执行”后台的.耗时的.重要的任务,三者缺一不可,而最重要的原因是第三点:要执行重要的任务. 因为当一个进程启动了Service后,进程的优先级变高了, ...

  3. spring 登录提示 Bad credentials

    spring 日志输出:Authentication failed: password does not match stored value in spring security 3.2,检查密码发 ...

  4. python中颜色设置

    实现过程: 终端的字符颜色使用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来表示(ESC是ASCII码用十进制表示是27,用八进制表示就是033 ...

  5. 【转】Python爬虫_示例

    爬虫项目:爬取汽车之家新闻资讯   # requests+Beautifulsoup爬取汽车之家新闻 import requests from bs4 import BeautifulSoup res ...

  6. VM and Docker Container

    https://www.zhihu.com/question/48174633 在开始讨论前,先抛出一些问题,可先别急着查看答案,讨论的过程可以让答案更有趣,问题如下: Docker 容器有自己的ke ...

  7. Linux yum源码包安装和卸载

    Linux 下的绝大多数源码包都是用 C 语言编写的,还有少部分是用 C++ 等其他程序语言编写的.所以,要想安装源码包,必须安装 C 语言编译器 gcc(如果是用 C++ 编写的程序,则还需要安装 ...

  8. qt的登录设置(转)

    1.下面添加代码来实现使用用户名和密码登录,这里只是简单将用户名和密码设置为了固定的字符串,如果以后学习了数据库,还可以通过读取数据库来获取用户名和密码.到logindialog.cpp文件中将登录按 ...

  9. linux 挂载 smb

    smbmount //192.168.1.210/homes/dm8168 /opt/fedora/ -o username=psubo,password=psubo_smb

  10. uCOS-II的学习笔记(共九期)和例子(共六个)

    源:uCOS-II的学习笔记(共九期)和例子(共六个) 第一篇 :学习UCOS前的准备工作http://blog.sina.com.cn/s/blog_98ee3a930100w0eu.html 第二 ...