HashMap 和 Hashtable 的同和不同
综述
可以直接根据 hashcode 值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的 hashcode 值。虽然不能根据 hashcode 值判断两个对象是否相等,但是可以直接根据 hashcode 值判断两个对象不等,如果两个对象的 hashcode 值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过 equals 方法。
也就是说对于两个对象,如果调用 equals 方法得到的结果为 true,则两个对象的 hashcode 值必定相等;如果 equals 方法得到的结果为 false,则两个对象的 hashcode 值不一定不同;如果两个对象的 hashcode 值不等,则 equals 方法得到的结果必定为 false;如果两个对象的 hashcode 值相等,则 equals 方法得到的结果未知。
HashMap 和 Hashtable 不保证 map 的顺序,也不保证顺序不会随着时间不变。
HashMap 实例有两个参数影响性能:初始 capacity 和 load factor。capacity 是 hashtable 中桶的数量,初始 capacity 就是 hashtable 创建时的 capacity。load factor 影响 hashtable 多满时允许自动增加 capacity。当 hashtable 中 entry 的数量超过 load factor 和当前 capacity 的乘积,hashtable 会重新哈希(意味着,内部数据结构重建)因此 hashtable 大约拥有桶数量的两倍。
作为通用规则,默认 load factor(0.75)在时间和空间消耗上提供了好的权衡。值越大,空间开销越小,但是遍历成本增加(表现在大多数操作,包括 get 和 put)。当设置初始 capacity 时,为了最小化重新 hash 的操作次数,应该考虑 map的 entry 数量和 load factor。如果初始容量大于最大 entry 数量除以 load factor ,重新 hash 操作将不会发生。然而,设置初始 capacity 太大会浪费空间。
如果许多 mapping 存储在 HashMap 实例中,创建时使用足够大的 capacity 将允许 mapping 存储得更有效率,因为不会随着 table 的数量增大重新 hash。注意使用许多相同 hashCode() 的 key 肯定会降低任意 hashtable 的性能。
相同点
成员变量 | 值 |
---|---|
DEFAULT_LOAD_FACTOR | 0.75 |
TREEIFY_THRESHOLD | 8 |
UNTREEIFY_THRESHOLD | 6 |
MIN_TREEIFY_CAPACITY否则resize() | 64 |
size | mapping 数量 |
threhold | capacity*load factor |
不同点
HashMap | Hashtable | |
---|---|---|
线程安全 | 不安全 | 安全 |
允许null的键和值 | 允许 | 不允许 |
实现和继承 | 实现Map | 实现Map,继承Dictionary |
遍历方式 | Iterator | Iterator和Enumeration |
计算哈希值 | (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16) | (key.hashCode() & 0x7FFFFFFF) |
计算数组下标 | (length - 1) & hash | hash % length |
DEFAULT_INITIAL_CAPACITY | 16 | 11 |
容量增加方式 | old*2长度始终为2的幂 | old*2+1 |
构造函数 | threshold=tableSizeFor(initialCapacity) | threhold=initialCapacity*load factor |
resize | 从0-cap链表顺序不变 | 从cap-0链表顺序相反 |
注意点:
计算数组下标:当length总是2的n次方时,h & (length - 1)运算等价于对 length 取模,也就是 h % length,但是&比%具有更高的效率。
容量增加方式:当数组长度为 2 的 n 次幂的时候,不同的 key 算得的 index 相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小。相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了。导致 resize() 不同 HashMap 直接使用之前的数组下表,而 Hashtable 需要重新计算。
HashMap 和 Hashtable 的同和不同的更多相关文章
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
- java面试题——HashMap和Hashtable 的区别
一.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Clonea ...
- Map集合及与Collection的区别、HashMap和HashTable的区别、Collections、
特点:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值. Map集合和Collection集合的区别 Map集合:成对出现 (情侣) ...
- HashMap和 Hashtable的比较
Hashtable 和 HashMap的比较 1. HashMap可以接受null(HashMap可以接受为null的键值(key)和值(value), HashTable不可以接受为null的键( ...
- hashMap和hashTable的区别
每日总结,每天进步一点点 hashMap和hashTable的区别 1.父类:hashMap=>AbstractMap hashTable=>Dictionary 2.性能:hashMap ...
- HashMap和HashTable到底哪不同?
HashMap和HashTable有什么不同?在面试和被面试的过程中,我问过也被问过这个问题,也见过了不少回答,今天决定写一写自己心目中的理想答案. 代码版本 JDK每一版本都在改进.本文讨论的Has ...
- java分享第七天-01(Hashmap和Hashtable的区别&Property)
一.Hashmap和Hashtable的区别 1 主要:Hashtable线程安全,同步,效率相对低下 HashMap线程不安全,非同步,效率相对高 2 父类:Hashtable是Dictionary ...
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...
- HashMap、HashTable、LinkedHashMap和TreeMap用法和区别
Java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap.HashTable.LinkedHashMap和TreeMap.本节实例主要介绍这4中实例的用 ...
- Java重点之小白解析--浅谈HashMap与HashTable
这是一个面试经常遇到的知识点,无论什么公司这个知识点几乎是考小白必备,为什么呢?因为这玩意儿太特么常见了,常见到你写一百行代码,都能用到好几次,不问这个问哪个.so!本小白网罗天下HashMap与Ha ...
随机推荐
- mysql查询的语法
单表查询语法 SELECT DISTINCT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条 ...
- day01_08.三大控制结构
编程三要素:变量,运算,控制 控制: 有选择性的控制让你某部分代码执行,某部分不执行,或者来回反复执行某段代码 控制的三种基本机构:顺序,选择,循环 1.顺序 程序从上到下,顺序执行 <?php ...
- Matplotlib中文乱码解决办法
Matplotlib中文乱码 解决方法如下: 首先设置源码文件编码方式为UTF-8 #-*- coding: utf-8 -*- 接着设置字体属性字典 font = {'family': 'SimHe ...
- Django数据库的查看、删除,创建多张表并建立表之间关系
配置以下两处,可以方便我们直接右键运行tests.py一个文件,实现对数据库操作语句的调试: settings里面的设置: #可以将Django对数据库的操作语法,能输出对应的的sql语句 LOGGI ...
- c++中set容器的功能及应用。
set的特性是,所有元素都会根据元素的键值自动排序(默认为升序),set中不允许两个元素有相同的键值. set基本操作: 1.头文件 #include<set>. 注:一定要加上using ...
- 相机拍照功能之权限和Android版本问题
代码改变世界 相机拍照功能之权限和Android版本问题 对于Android 6.0之前,想要使用系统的相机进行拍照,那么只要在AndroidManifedt.xml中进行添加相应的权限,主要是两个: ...
- 【bzoj2698】染色 期望
题目描述 输入 输入一行四个整数,分别为N.M.S和T. 输出 输出一行为期望值,保留3位小数. 样例输入 5 1 2 3 样例输出 2.429 题解 期望 由于期望在任何时候都是可加的,因此只要算出 ...
- kb-07线段树--11--区间多重该值多种查询
/* lazy思想的运用,因为查询多种,如果全记录就太繁了,lazy就是如果该区间的每一个叶子的状态都相同就不用深入下去该值,只要暂时标记下,查询的时候也不用下去,直接计算: */ #include& ...
- 数组快速生成range的方法
//生成[item1-item9]数组 Array(9).join(0).split('').map((item,index) => 'item' + (index+1)) //生成20个对象的 ...
- 数据库操作之——key与index的区别
mysql的key和index多少有点令人迷惑,这实际上考察对数据库体系结构的了解的. 1 key 是数据库的物理结构,它包含两层意义,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查 ...