Java中的集合(十三) 实现Map接口的Hashtable
Java中的集合(十三) 实现Map接口的Hashtable
一、Hashtable简介
和HashMap一样,Hashtable采用“拉链法”实现一个哈希表,它存储的内容是键值对(key-value)映射。Hashtable 的实例有两个参数影响其性能:初始容量 (11)和 加载因子(0.75)。容量 是哈希表中桶 的数量,初始容量 就是哈希表创建时的容量。注意,哈希表的状态为 open:在发生“哈希冲突”的情况下,单个桶会存储多个条目,这些条目必须按顺序搜索。加载因子 是对哈希表在其容量自动增加之前可以达到多满的一个尺度。初始容量和加载因子这两个参数只是对该实现的提示。关于何时以及是否调用 rehash 方法的具体细节则依赖于该实现。
通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查找某个条目的时间(在大多数 Hashtable 操作中,包括 get 和 put 操作,都反映了这一点)。
(一)、Hashtable与Map接口的关系
二、Hashtable的继承结构
Hashtable继承Dictionary,实现了Map、Cloneable和Serializable接口。Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。此外,Hashtable中的映射不是有序的。
三、Hashtable的构造方法
四、Hashtable主要成员属性
Hashtable采用"拉链法"实现哈希表,它定义了几个重要的参数:table、count、threshold、loadFactor、modCount。
1、table
是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的"key-value键值对"都是存储在Entry数组中的。
2、count
是Hashtable的大小,它是Hashtable保存的键值对的数量。
3、threshold
是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值="容量 * 加载因子"。
4、loadFactor
加载因子,默认为0.75。
5、modCount
是用来实现fail-fast机制的。
五、Hashtable的遍历方式
(一)、迭代器的遍历方式
Hashtable的迭代器遍历方式和HashMap的基本一致,可参考Java集合(十)实现Map接口的HashMap 的遍历方式。
(二)、Enumeration(枚举器)遍历
1、通过Enumeration遍历Hashtable的键
①、通过keys方法获得Enumeration<K>枚举器集合
②、通过Enumeration遍历
// 假设Hashtable的键为String类型,值为Integer类型
Hashtable<String,Integer> table = new Hashtable<String,Integer>();
Enumeration<String> enu = table.keys();
while(enu.hasMoreElements()) {
String str = enu.nextElement();
}
2、通过Enumeration遍历Hashtable的值
①、通过elements方法Enumeration<K>枚举器集合
②、通过Enumeration遍历
Enumeration<Integer> enu = table.elements();
while(enu.hasMoreElements()) {
Integer i = enu.nextElement();
}
六、Hashtable常用API
七、Hashtable与HashMap的异同
(一)、相同点
1、HashMap和Hashtable都是存储“键值对(key-value)”的散列表,而且都是采用拉链法实现的。
存储的思想都是:通过table数组存储,数组的每一个元素都是一个Entry;而一个Entry就是一个单向链表,Entry链表中的每一个节点就保存了key-value键值对数据。
①、添加key-value键值对:首先,根据key值计算出哈希值,再计算出数组索引(即,该key-value在table中的索引)。然后,根据数组索引找到Entry(即,单向链表),再遍历单向链表,将key和链表中的每一个节点的key进行对比。若key已经存在Entry链表中,则用该value值取代旧的value值;若key不存在Entry链表中,则新建一个key-value节点,并将该节点插入Entry链表的表头位置。
②、删除key-value键值对:删除键值对,相比于“添加键值对”来说,简单很多。首先,还是根据key计算出哈希值,再计算出数组索引(即,该key-value在table中的索引)。然后,根据索引找出Entry(即,单向链表)。若节点key-value存在与链表Entry中,则删除链表中的节点即可。
2、加载因子都是0.75。
(二)、不同点
1、继承方式不同。
HashMap继承AbstractMap,Hashtable继承Dictionary,但是同样实现了Map、Cloneable、java.io.Serializable接口。
2、线程安全不同。
HashMap是非同步,线程不安全的;Hashtable是同步到,线程安全的。
3、存储null处理方式。
HashMap的键值都可以为null,Hashtable的键值都不可以为null。
4、遍历方式不同。
HashMap只支持获取迭代器遍历;Hashtable支持Iterator(迭代器)和Enumeration(枚举器)两种方式遍历。
5、容量的初始值不同。
HashMap初始值默认为16;Hashtable默认为11。
6、增加方式不同。
当HashMap的 “实际容量” >= “阈值”时,(阈值 = 总的容量 * 加载因子),就将HashMap的容量翻倍;
Hashtable的 “实际容量” >= “阈值”时,(阈值 = 总的容量 x 加载因子),就将变为“原始容量x2 + 1”。
7、添加key-value时的hash值计算方式不同。
HashMap添加kley-value时,采用的是自定义的哈希算法计算hash值;
Hashtable没有自定义哈希算法,而是采用key的hashCode(当自定义对象是必须重写hashCode和equals方法)。
Java中的集合(十三) 实现Map接口的Hashtable的更多相关文章
- Java中的集合(十一) 实现Map接口的TreeMap
Java中的集合(十一) 实现Map接口的TreeMap 一.TreeMap简介(基于JDK1.8) TreeMap是基于红黑树数据结构,是一个key-value的有序集合,该映射根据其键的自然顺序进 ...
- Java中的集合(十四) Map的实现类LinkedHashMap
Java中的集合(十四) Map的实现类LinkedHashMap 一.LinkedHashMap的简介 LinkedHashMap是Map接口的实现类,继承了HashMap,它通过重写父类相关的方法 ...
- Java中的集合(Set,List,Map)
******************collections类总结*************************** JAVA集合主要分为三种类型: Set(集) List(列表) ...
- Java学习--java中的集合框架、Collection接口、list接口
与数组相比:1.数组的长度固定,而集合的长度可变2.数组只能通过下表访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象 java集合框架:collection(list序列,queue ...
- C#与java中的集合区别
集合一般的操作 插入: add 删除: remove 查找: contains,remove java中的集合 注意哪些是接口,哪些是实现类 使用集合的时候 1. ...
- Java 中的集合接口——List、Set、Map
Java 中的集合接口——List.Set.Map 什么叫集合:集合就是Java API所提供的一系列类的实例,可以用于动态存放多个对象.这跟我们学过的数组差不多,那为什么我们还要学集合,我们看看数组 ...
- Java中的集合(十二) 实现Map接口的WeakHashMap
Java中的集合(十二) 实现Map接口的WeakHashMap 一.WeakHashMap简介 WeakHashMap和HashMap一样,WeakHashMap也是一个哈希表,存储的也是键值对(k ...
- Java中的集合(七)双列集合顶层接口------Map接口架构
Java中的集合(七)双列集合顶层接口------Map接口 一.Map接口的简介 通过List接口,我们知道List接口下的集合是单列集合,数据存储是单列的结构.Map接口下是一个键值对(key-v ...
- Java中的集合框架-Map
前两篇<Java中的集合框架-Commection(一)>和<Java中的集合框架-Commection(二)>把集合框架中的Collection开发常用知识点作了一下记录,从 ...
随机推荐
- P4768 [NOI2018]归程(kruskal 重构树)
洛谷P4768 [NOI2018]归程 LOJ#2718.「NOI2018」归程 用到 kruskal 重构树,所以先说这是个啥 显然,这和 kruskal 算法有关系 (废话 这个重构树是一个有点权 ...
- 一个epoll的简单例子
epoll事件机制的触发方式有两种:LT(电平触发)和ET(边沿触发) EPOLLIN事件: 内核中的socket接收缓冲区 为空(低电平) 内核中的socket接受缓冲区 不为空(高电平) EPOL ...
- Spring IOC的核心机制:实例化与注入
上文我们介绍了IOC和DI,IOC是一种设计模式,DI是它的具体实现,有很多的框架都有这样的实现,本文主要以spring框架的实现,来看具体的注入实现逻辑. spring是如何将对象加入容器的 spr ...
- 【学习笔记:Python-网络编程】Socket 之初见
Socket 是任何一种计算机网络通讯中最基础的内容.当你在浏览器地址栏中输入一个地址时,你会打开一个套接字,可以说任何网络通讯都是通过 Socket 来完成的. Socket 的 python 官方 ...
- 区间dp E - Multiplication Puzzle POJ - 1651
E - Multiplication Puzzle POJ - 1651 这个题目没有特别简单,但是也没有我想象之中的那么难,这个题目时区间dp,因为我们是要对区间进行考虑的. 但是呢,这个也和动态 ...
- java基础篇 之 非静态内部类
什么是非静态内部类: public class Outer { Outer() { System.out.println("我是外部类"); } class Inner { Inn ...
- 测试开发专题:spring-boot统一异常捕获
java异常介绍 异常时相对于return的一种退出机制,可以由系统触发,也可由程序通过throw语句触发,异常可以通过try/catch语句进行捕获并处理,如果没有捕获,则会导致程序退出并输出异常栈 ...
- Try-Catch包裹的代码异常后,竟然导致了产线事务回滚!
导读:一段被try-catch包裹后的代码在产线稳定运行了200天后忽然发生了异常,而这个异常竟然导致了产线事务回滚.这期间究竟发生了什么?日常在项目过程中该如何避免事务异常?就在这个时候,老板拿着 ...
- 一文教你快速修改ubuntu终端显示的主机名和用户名
为了让终端的显示更加简洁,清爽,改掉显示的用户名和主机名,改成你喜欢的名字. 创作不易,如果本文帮到了您: 如果本文帮到了您,请帮忙点个赞
- go实现SnowFlake
package main import ( "errors" "fmt" "strconv" "sync" " ...