一、---使用方式---

(1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。

(2)Hashtable 继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。

(3)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。

如下是Hashtable 的简单使用方式:在遍历时使用是三种遍历方式来对其进行遍历

package ThreeWeek;
 
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
 
public class HashTableTest {
 
    public static void main(String args[]){
        Hashtable<String, Integer> table = new Hashtable<String, Integer>();
        
        //[1]添加元素
        table.put("zhangsan", 22);
        table.put("lisi", 33);
        table.put("wangwu", 44);
        
        //[2]toString()方式打印
        System.out.println(table.toString());
        
        //[3]Iterator遍历方式1--键值对遍历entrySet()
        Iterator<Entry<String, Integer>> iter = table.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry<String, Integer> entry = (Map.Entry<String, Integer>)iter.next();
            String key = entry.getKey();
            int value = entry.getValue();
            System.out.println("entrySet:"+key+" "+value);
        }
        
        System.out.println("====================================");
        
        //[4]Iterator遍历方式2--key键的遍历
        Iterator<String> iterator = table.keySet().iterator();
        while(iterator.hasNext()){
            String key = (String)iterator.next();
            int value = table.get(key);
            System.out.println("keySet:"+key+" "+value);
        }
        
        System.out.println("====================================");
        
        //[5]通过Enumeration来遍历Hashtable
        Enumeration<String> enu = table.keys();
        while(enu.hasMoreElements()) {
            System.out.println("Enumeration:"+table.keys()+" "+enu.nextElement());
        } 
            
    }
}
--------------------output--------------------

{zhangsan=22, lisi=33, wangwu=44}
entrySet:zhangsan 22
entrySet:lisi 33
entrySet:wangwu 44
====================================
keySet:zhangsan 22
keySet:lisi 33
keySet:wangwu 44
====================================
Enumeration:java.util.Hashtable$Enumerator@139a55 zhangsan
Enumeration:java.util.Hashtable$Enumerator@1db9742 lisi
Enumeration:java.util.Hashtable$Enumerator@106d69c wangwu

二、---内部原理---

1、继承关系

java.lang.Object
   ↳     java.util.Dictionary<K, V>
         ↳     java.util.Hashtable<K, V>
 
public class Hashtable<K,V> extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable { }
与HashMap不同的是Hashtable是继承Dictionary,实现了Map接口。Map是"key-value键值对"接口,Dictionary是声明了操作"键值对"函数接口的抽象类。

2、构造函数

(1)Hashtable中提供了四个构造函数,如下:

// 默认构造函数。
public Hashtable() 
 
// 指定“容量大小”的构造函数
public Hashtable(int initialCapacity) 
 
// 指定“容量大小”和“加载因子”的构造函数
public Hashtable(int initialCapacity, float loadFactor) 
 
// 包含“子Map”的构造函数
public Hashtable(Map<? extends K, ? extends V> t)

(2)上面的四个构造方法中,第三个是最重要的,指定初始化容量和构造因子

public Hashtable(int initialCapacity, float loadFactor) {  
        //验证初始容量  
        if (initialCapacity < 0)  
            throw new IllegalArgumentException("Illegal Capacity: "+  
                                               initialCapacity);  
        //验证加载因子  
        if (loadFactor <= 0 || Float.isNaN(loadFactor))  
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);  
  
        if (initialCapacity==0)  
            initialCapacity = 1;  
          
        this.loadFactor = loadFactor;  
          
        //初始化table,获得大小为initialCapacity的table数组  
        table = new Entry[initialCapacity];  
        //计算阀值  
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);  
        //初始化HashSeed值  
        initHashSeedAsNeeded(initialCapacity);  
    }

3、成员变量

(1)table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的"key-value键值对"都是存储在Entry数组中的。

(2)count是Hashtable的大小,它是Hashtable保存的键值对的数量。

(3)threshold是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值="容量*加载因子"。

(4)loadFactor就是加载因子。

(5)modCount是用来实现fail-fast机制的

private transient Entry[] table;
// Hashtable中元素的实际数量
private transient int count;
// 阈值,用于判断是否需要调整Hashtable的容量(threshold = 容量*加载因子)
private int threshold;
// 加载因子
private float loadFactor;
// Hashtable被改变的次数
private transient int modCount = 0;

4、put和get方法
(1)put方法

从下面的代码中我们可以看出,Hashtable中的key和value是不允许为空的,当我们想要想Hashtable中添加元素的时候,首先计算key的hash值,然

后通过hash值确定在table数组中的索引位置,最后将value值替换或者插入新的元素,如果容器的数量达到阈值,就会进行扩充。

public synchronized V put(K key, V value) {  
        // 确保value不为null  
        if (value == null) {  
            throw new NullPointerException();  
        }  
  
        /* 
         * 确保key在table[]是不重复的 
         * 处理过程: 
         * 1、计算key的hash值,确认在table[]中的索引位置 
         * 2、迭代index索引位置,如果该位置处的链表中存在一个一样的key,则替换其value,返回旧值 
         */  
        Entry tab[] = table;  
        int hash = hash(key);    //计算key的hash值  
        int index = (hash & 0x7FFFFFFF) % tab.length;     //确认该key的索引位置  
        //迭代,寻找该key,替换  
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
            if ((e.hash == hash) && e.key.equals(key)) {  
                V old = e.value;  
                e.value = value;  
                return old;  
            }  
        }  
  
        modCount++;  
        if (count >= threshold) {  //如果容器中的元素数量已经达到阀值,则进行扩容操作  
            rehash();  
            tab = table;  
            hash = hash(key);  
            index = (hash & 0x7FFFFFFF) % tab.length;  
        }  
  
        // 在索引位置处插入一个新的节点  
        Entry<K,V> e = tab[index];  
        tab[index] = new Entry<>(hash, key, value, e);  
        //容器中元素+1  
        count++;  
        return null;  
    }

(2)get方法
同样也是先获得索引值,然后进行遍历,最后返回

public synchronized V get(Object key) {  
        Entry tab[] = table;  
        int hash = hash(key);  
        int index = (hash & 0x7FFFFFFF) % tab.length;  
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
            if ((e.hash == hash) && e.key.equals(key)) {  
                return e.value;  
            }  
        }  
        return null;  
    }

五、---比较不同---

Hashtable和HashMap到底有哪些不同呢
(1)基类不同:HashTable基于Dictionary类,而HashMap是基于AbstractMap。Dictionary是什么?它是任何可将键映射到相应值的类的抽象父类,而AbstractMap是基于Map接口的骨干实现,它以最大限度地减少实现此接口所需的工作。

(2)null不同:HashMap可以允许存在一个为null的key和任意个为null的value,但是HashTable中的key和value都不允许为null。

(3)线程安全:HashMap时单线程安全的,Hashtable是多线程安全的。

(4)遍历不同:HashMap仅支持Iterator的遍历方式,Hashtable支持Iterator和Enumeration两种遍历方式。

尊重作者,尊重原创,参考文章:

http://www.cnblogs.com/skywang12345/p/3310887.html#a1

http://cmsblogs.com/?p=618
--------------------- 
作者:劲火星空 
来源:CSDN 
原文:https://blog.csdn.net/jinhuoxingkong/article/details/52022999 
版权声明:本文为博主原创文章,转载请附上博文链接!

Hashtable的原理相关推荐

  1. 调试JDK源码-Hashtable实现原理以及线程安全的原因

    调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hash ...

  2. java hashtable 数据结构_java Hashtable底层原理是怎样的?数据结构包括什么?

    大家都知道,随着近些年科学技术水平的不断进步与发展,学习编程语言的人也越来越多了.很多人对于java中的一些常见知识点有些不了解,今天就来为大家详细介绍一下. 首先说一下具体的概念: HashTabl ...

  3. hashmap原理_HashMap和HashTable底层原理以及区别

    HashMap底层原理 哈希表:在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1). 数据结构的物理存储结构只有两种:顺序存储结构和 ...

  4. 源码解析-深刻理解Hash HashTable HashMap原理及数据hash碰撞问题

    HashMap 前言 Hash HashTable 开地址法 线性探测法 平方探测法 双重散列探测法 拉链法 哈希表优势 HashMap 变量介绍 初始容量和负载因子 红黑树和链表转化 HashMap ...

  5. 调试JDK源码-ConcurrentHashMap实现原理

    调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hash ...

  6. 调试JDK源码-HashSet实现原理

    调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hash ...

  7. hashtable源码解析

    Hashtable 也就是哈希表,是个非常重要的概率,在剖析hashtable源码前,我先简单介绍一下hashtable的原理 哈希表概念 什么是哈希(hash又称散列)? 将任意长度的消息压缩到某一 ...

  8. 开放地址法实现HashTable

    前注:本文不是讲解Java类库的Hashtable实现原理,而是根据计算机哈希表原理自己实现的一个Hashtable. HashTable内部是用数组存放一个(Key-Value pair)键值对的引 ...

  9. Java 集合系列11: Hashtable深入解析(1)

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 QQ群:766946816 概要 前一章,我们学习了HashMap.这一 ...

最新文章

  1. 优雅处理你的Java异常
  2. 日志文件列表 读书笔记《Linux 系统管理技术手册(第二版)》
  3. PCL中异常处理机制
  4. drawable自定义字体颜色
  5. 《快速构建Windows 8风格应用》系列文章汇总
  6. Maven -- group、artifact、package
  7. 在linux中的sort命令,linux中sort命令
  8. Android WebView中使用loadData时出现的乱码问题解决办法
  9. 一个用Axure开发的安卓Android智能交通app的mockup
  10. Android之Andorid studio 解决Error:Configuration with name ‘default‘ not found
  11. leetcode116. 填充每个节点的下一个右侧节点指针(dfs)
  12. C#中写入Excel
  13. cmake取消宏定义_魔兽怀旧服,牧师实用宏
  14. 编辑,修改chm帮助文档,无需修改繁琐的html文件,可以直接编辑修改chm
  15. PS常用快捷键及模板使用
  16. echarts三维建筑地图注解
  17. h5游戏抽奖游戏源码_抽奖扑克游戏
  18. Windows访问共享文件报错:请检查名称拼写。否则,网络可能有问题
  19. 使用非对称加密匿名加好友
  20. 如何使用分布是缓存Hazelcast

热门文章

  1. 批量复制到花瓣网上图片素材的原图
  2. 新项目上传之svn服务器
  3. FastAPI简单入门
  4. 深度强化学习(DRL)简介与常见算法(DQN,DDPG,PPO,TRPO,SAC)分类
  5. 链表-双向链表(C语言)
  6. 电脑更改开机密码和用户名
  7. redis:cluster nodes、cluster slaves node-id
  8. 7.Docker容器使用辅助工具汇总
  9. 计算机技术英文缩写含义,电脑技术中常见的英文缩写含义
  10. SpringCloud Getway服务网关