Hashtable简介

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

Hashtable在Java中的定义为:

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable

从源码中可以看出,Hashtable继承于Dictionary,实现了Map、Cloneable、Serializable接口。其中Dictionary类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类。Hashtable的函数都是同步的,这意味着它是线程安全的。key、value都不可以为null。此外,Hashtable中的映射不是有序的。

Hashtable是通过“拉链法”实现的哈希表。它包括几个重要的成员变量:table, count, threshold, loadFactor, modCount

  • table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的“key-value键值对”都是存储在Entry数组中的。
  • count是Hashtable的大小,它是Hashtable保存的键值对的数量。
  • threshold是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值=”容量*加载因子”。
  • loadFactor就是加载因子。
  • modCount是用来实现fail-fast机制的

部分源码解析:

构造方法

// 指定“容量大小”和“加载因子”的构造函数
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 = new Entry[initialCapacity];
    threshold = (int)(initialCapacity * loadFactor);
}

// 指定“容量大小”的构造函数
public Hashtable(int initialCapacity) {
    this(initialCapacity, 0.75f);
}

// 默认构造函数
public Hashtable() {
    // 指定容量大小为11,加载因子为0.75
    this(11, 0.75f);
}

// 构造一个与给定的 Map 具有相同映射关系的新哈希表
public Hashtable(Map<? extends K, ? extends V> t) {
    this(Math.max(2*t.size(), 11), 0.75f);
    putAll(t);
}

put() 方法

public synchronized V put(K key, V value) {
    // 确保value不为空,否则抛异常
    if (value == null) {
        throw new NullPointerException();
    }

    //确保key不在hashtable中
        //首先,通过hash方法计算key的哈希值,并计算得出index值,确定其在table[]中的位置
        //其次,迭代index索引位置的链表,如果该位置处的链表存在相同的key,则替换value,返回旧的value
    Entry tab[] = table;
    int hash = key.hashCode();
    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)) {
        V old = e.value;
        e.value = value;
        return old;
        }
    }

    modCount++;
    if (count >= threshold) {
        // 若超过阈值,则进行rehash扩容操作
        rehash();

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
    }

    // 将Hashtable中index位置的Entry(链表)保存到e中
    Entry<K,V> e = tab[index];
    tab[index] = new Entry<K,V>(hash, key, value, e);
    count++;
    return null;
}

get() 方法

其过程首先通过hash()方法或得key的哈希值,然后根据hash值得等index所有,然后迭代链表,返回匹配的key对应的value,没有的话返回null。

public synchronized V get(Object key) {
    Entry tab[] = table;
    // 得等hash值
    int hash = key.hashCode();
    // 计算索引值
    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实现原理及源码分析的更多相关文章

  1. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...

  2. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  3. HashMap实现原理及源码分析之JDK8

    继续上回HashMap的学习 HashMap实现原理及源码分析之JDK7 转载 Java8源码-HashMap  基于JDK8的HashMap源码解析  [jdk1.8]HashMap源码分析 一.H ...

  4. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  5. (转)ReentrantLock实现原理及源码分析

    背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...

  6. 【转】HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  7. 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

    原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论   自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...

  8. 《深入探索Netty原理及源码分析》文集小结

    <深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de

  9. 【OpenCV】SIFT原理与源码分析:关键点描述

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<方向赋值>,为找到的关键点即SI ...

随机推荐

  1. shell 算术运算符

    算术运算符 下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20: 运算符 说明 举例 + 加法 `expr $a + $b` 结果为 30. - 减法 `expr $a - $b` ...

  2. TinyXml节点查找及修改

    参考:http://blog.csdn.net/zww0815/article/details/8083550 // 读者对象:对TinyXml有一定了解的人.本文是对TinyXml工具的一些知识点的 ...

  3. 原始的生成对抗网络GAN

    论文地址:https://arxiv.org/pdf/1406.2661.pdf 1.简介: GAN的两个模型 判别模型:就是图中右半部分的网络,直观来看就是一个简单的神经网络结构,输入就是一副图像, ...

  4. jq的attr()与prop()之间区别

    1.attr() 一直存在,prop() 仅存在于 jq-1.6 及其之后 2.新版本jq使用细节: 2.1 自定义添加至dom节点的属性,用attr获取 2.2 表单类checked.selecte ...

  5. 远程SqlServer服务器

    ①,安装net framework3.5. ②,安装sqlserver2014(例). ③,基本配置. 安装sqlserver2014时,开启混合认证模式.当然,也可以在安装后,通过sqlserver ...

  6. centos7: iptables保存(配置完nginx的web规则后)

    centos7: iptables保存(配置完nginx的web规则后) 以本地虚拟机为例: 添加规则:入站规则 iptables -I INPUT -p tcp --dport 80 -j ACCE ...

  7. php--------获取当前时间、时间戳

    首先需要知道的是在php中获取时间方法是date(),在php中获取时间戳方法有time().strtotime().下面分别说明. date() 格式为:date($format, $timesta ...

  8. 在 Confluence 6 中连 Jira 的问题解决

    下面是可能会发生的一些错误信息.如果你的系统中出现了下面的一些提示,你应该调整你的日志错误级别到 WARN,然后查看具体的错误原因.请参考:Configuring Logging. error.jir ...

  9. ajax中文乱码问题的总结

    ajax中文乱码问题的总结 2010-12-11 22:00 5268人阅读 评论(1) 收藏 举报 ajaxurljavascriptservletcallback服务器 本章解决在AJAX中常见的 ...

  10. 全源最短路径 - floyd算法 - O(N ^ 3)

    Floyd-Warshall算法的原理是动态规划. 设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度. 若最短路径经过点k,则Di,j,k = Di,k,k − 1 + ...