java Hashtable及其子类Properties 源码分析(通俗易懂)

2023-11-17

目录

一、前言

二、Hashtable详解

        1.简介

        2.特点

        3.底层实现

        4.HashMap VS Hashtable

三、Properties详解

        1.简介

        2.特点

        3.具体使用(可以不看)

四、完结撒❀


一、前言

        大家好,本篇博文是对Map接口常用实现类之一Hashtable类的源码分析,顺便讲一下它的子类Properties,考虑到Hashtable的使用频率,up不会像HashMap那样讲得很细致,但是底层的东西该说都会说的,比一般地方讲得还是要细点。
        注意 : ①解读源码需要扎实的基础,比较适合希望深究的同学;不要眼高手低,看会了不代表你会了,自己能跟着过一遍才算有收获; 点击文章的侧边栏目录或者前面的目录可以进行跳转。 良工不示人以朴,up所有文章都会适时改进。大家有问题都可以在评论区讨论交流,或者私信up。 感谢阅读!


二、Hashtable详解

        1.简介

        Hashtable是Map接口的一个实现类,地位上与HashMap平起平坐。Hashtable也属于java.base模块,java.util包下,如下图所示 : 

        我们再来看看Hashtable的类图,如下


        2.特点

        Hashtable中保存的也是key-value键值对,不过特别的是Hashtable键值对中的"key"和"value"都不能为null,否则会抛出nullPointerException异常
        2° Hashtable中的一些常用方法在用法上基本和HashMap中的一致,比如put方法。
        Hashtable中的成员方法用了synchronized关键字修饰,因此Hashtable是线程安全的,而HashMap是线程不安全的。


        3.底层实现

       
        为了通过Debug来给大家分析Hashtable的源码,up以Hashtable_Demo类作为演示类来进行断点调试。Hashtable_Demo类代码如下 : (main函数第一行设置断点)

package csdn.knowledge.api_tools.gather.map;

import java.util.Hashtable;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
public class Hashtable_Demo {
    public static void main(String[] args) {
        Hashtable hashtable = new Hashtable();

        hashtable.put(1, 141);
        hashtable.put(2, 141);
        hashtable.put(3, 141);
        hashtable.put(4, 141);
        hashtable.put(5, 141);
        hashtable.put(6, 141);
        hashtable.put(7, 141);
        hashtable.put(8, 141);
        hashtable.put(9, "这是集合第9个元素捏");

        System.out.println(hashtable);
    }
}

        1°
        
Hashtable底层维护了Hashtable$Entry类型的数组table,用于存放键值对,如下图所示 : 

        通过查看Hashtable的源码能够找到这个Entry类型,如下图所示 : 

        可以看到,Hashtable$Entry其实就是Hashtable的一个静态内部类,并且同HashMap中的内部类HashMap$Node类一样,也实现了Map接口中的Entry内部接口
       
        利用无参构造初始化Hashtable类对象时,会将底层的table数组初始化为长度等于11的数组。同样我们可以通过追溯Hashtable无参构造的源码来找到依据,如下 : 

        可以看到,Hashtable的无参构造,其实底层调用的是本类的一个有参构造,并且通过传入的实参我们可以得到以下信息——table数组的初始容量 = 11;加载因子 = 0.75。这俩就不用我多说了,都是老面孔了。
        我们可以进入追进入这个有参构造中看看,如下图所示 : 

        别的不说,直接看最后两行将new出的长度 = 11的Entry类型的数组赋值给了table数组,这条语句解释了table数组的初始容量为什么是11。
        同时,threshold(临界值)被赋值为8。这个8是怎么来的?其实和我们之前讲得HashMap底层一样,threshold = table数组的长度 * 加载因子 = 11 * 0.75 = 8.25,因为此处进行了int类型的强制向下转型,所以最后赋值给threshold变量的是8,初始临界值 = 8。
        关于"临界值有什么用"的问题up在之前的源码分析中讲过很多次了,这里只回顾一点——在HashMap底层中,当table数组中元素的个数超过临界值,就要对table数组进行扩容。
        3° 
        对于Hashtable底层的table数组,其扩容时采用了"2n + 1"的机制。具体解释我们可以结合源码来看,如下图所示 : 

        先向table数组中加入8个元素,可以看到此时集合中键值对的个数count = 8,等于此时table数组的临界值threshold。此时,如果我们向集合中添加第9个元素,table数组就会进行扩容操作。我们可以通过Debug,来追一下添加第9个元素的put方法。首先我们进入put方法,如下图所示 : 

        在put方法中我们发现,真正完成添加元素的操作是在addEntry方法中进行的,因此,我们继续追入addEntry方法如下图所示

        观察addEntry方法的源码,我们可以清楚地看到Hashtable类和HashMap类在扩容时明显的两点不同——
        ①具体代码的执行顺序不同 : 
        
HashMap底层是先完成添加元素的操作,再进行临界值的判断——如果当前元素加入集合后,会使得集合中元素的个数大于临界值threshold,就会跳入resize方法对table数组进行扩容
        而Hashtable则是先进行临界值的判断,再完成添加元素的操作——如果当前集合中元素的个数已经达到或超过当前的临界值,就会先跳入rehash方法对table数组进行扩容操作,等扩容成功后,再回来把当前键值对加入table数组中
        ②对临界值的判断条件不同 : 
        HashMap底层对于临界值的判断条件是——如果当前集合中元素的个数大于当前临界值threshold,就进入resize方法对table数组进行扩容
        PS : 大家可能对HashMap底层的一些东西忘了,up将图放下面 : 

        而Hashtable对于临界值的判断条件却是——如果当前集合中元素的个数大于等于(达到或超过)当前临界值threshold,就进入rehash方法对table数组进行扩容
        当然,以上两点只是内在底层的一些不同,如果从外在宏观上来看,从结果上来看,其实这俩还是一样的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java Hashtable及其子类Properties 源码分析(通俗易懂) 的相关文章

随机推荐

  • INFO zookeeper.ClientCnxn: Opening socket connection to server***/192.168.80.151:2181. Will not

    at org apache zookeeper ClientCnxnSocketNIO doTransport ClientCnxnSocketNIO java 361 at org apache zookeeper ClientCnxn
  • win10查看端口号是否被占用及解除占用的常用命令

    netstat ano 查看所有端口号占用情况 netstat ano findstr XXX 查看端口号为XXX的占用情况 如下 得到进程号为12160的进程正在占用本地的9090端口号 如果只是想释放9090端口到这一步就可以了 我们可
  • JDBC操作

    在IDEA中用java中驱动数据库 并使用Java语言操作数据库 10 1 数据库驱动 驱动 比如 声卡 显卡 数据库 我们的程序会通过数据库驱动和数据库打交道 10 2 JDBC sun公司为了简化开发人员的 对数据库的统一 操作 提供了
  • 我零基础,非计算机专业,想快速学习一门编程语言可行吗?

    都说要真正掌握一门编程语言 是件很困难的事情 尤其对于初学者而言 这话说的的确有几分道理 但其实学习编程语言的难度也并没有大多数人想的那么大 因为每个人学习会因为多种因素而有所不同 例如个人学习能力 学习背景 学习时间 编程语言本身等等 首
  • 什么是归纳偏置

    首先给出百度百科的定义 当学习器去预测其未遇到过的输入的结果时 会做一些假设 Mitchell 1980 而学习算法中归纳偏置则是这些假设的集合 是指在学习算法之初就通过人为偏好 将某一种解决方案优先于其他解 这既可以包含在底层数据分布假设
  • python实现对LabelImg标注的xml文件修改其标签名字

    使用labelImg标注数据时 通过python批量修改已经标注的数据标签名字 例如 本程序将标注生成的xml文件中的目标名字 zero 批量修改为 num 示例程序如下 通过解析xml文件 批量修改xml文件里的标签名称 比如把标签zer
  • NodeMcu arduino ESP8266WIFI 模块 例程 WIFIClienBasic(TCP服务器发送信息)

    NodeMcu arduino ESP8266WIFI 模块 WIFIClienBasic TCP服务器发送信息 流程 配置连接网络 发送TCP请求 获取接受数据打印 This sketch sends a string to a TCP
  • 【机器学习】LSTM 讲解

    2 LSTM 2 1 长期依赖问题 标准 RNN 结构在理论上完全可以实现将最初的信息保留到即使很远的时刻 但是在实践中发现 RNN 会受到短时记忆的影响 如果一条序列足够长 那它们将很难将信息从较早的时刻传送到后面的时刻 因此 如果正在尝
  • linux内核的构建系统,技术

    介绍 我不会告诉你怎么在自己的电脑上去构建 安装一个定制化的 Linux 内核 这样的资料太多了 它们会对你有帮助 本文会告诉你当你在内核源码路径里敲下make 时会发生什么 当我刚刚开始学习内核代码时 Makefile 是我打开的第一个文
  • pandas里面时间戳转时间to_datetime注意unit

    Using pandas to datetime with timestamps 遇到在pandas里面时间戳转时间的问题 把查到的答案记录在这里 主要注意to datetime函数里面的单位unit默认是毫秒ms 而非秒 而一般的10位时
  • [NAS]AutoML: A Survey of the State-of-the-Art

    AutoML A Survey of the State of the Art 自动机器学习 无需人类辅助自动进行机器学习 Abstract 本文根据AutoML的处理流程来对自动机器学习进行介绍 包括 数据准备 特征工程 超参数优化和神经
  • c++STL容器vector的复制

    将一个vector复制到另一个vector中 将一个vector v1 复制到另一个vector v2 中有两种方法 我知道的两种 囧 1 v2 v1 2 v2 assign v1 begin v1 end 两种方法的效果是一样的 vect
  • C++语言学习日志2.26

    初入C 跟C语言很多都很相似 主要从不同之处学习 1 I O流控制 流是一种抽象概念 他代表了数据的无结构化传递 按照流的方式进行输入输出 数据被当成无结构的字节序或字符序列 从流中取得数据的操作称为提取操作 而向流中添加数据的操作称为插入
  • 面试必问的MySQL锁与事务隔离级别

    之前多篇文章从mysql的底层结构分析 sql语句的分析器以及sql从优化底层分析 还有工作中常用的sql优化小知识点 面试各大互联网公司必问的mysql锁和事务隔离级别 这篇文章给你打神助攻 一飞冲天 锁定义 锁是计算机协调多个进程或线程
  • centos中apache使用教程

    一 安装Apache服务 1 检查是否安装了Apache服务器软件 rpm qa grep i httpd 2 查看apache2的命令 httpd V 3 停止和重启apache 其中HTTPD ROOT和SERVER CONFIG FI
  • 怎么成为一个软件架构师

    的确没想到随手写的东西有那么多的回复 不管怎样还是挺高兴的 在这里谢谢大家的关注了 其实做了这么多年的技术脑子里总会跳出很多的想法 但很少有时间静下来仔细地思考思考 写写博客也算是一种自我归纳和总结吧 软件架构师 这个名词也不知是什么时候进
  • 【三维重建学习之路01】点云ply文件的读写、修改

    文章目录 1 前言 2 PLY文件格式 3 读文件 变量 库 查看头文件 vertex信息 数据类型 读文件函数 按行阅读检查 4 写文件 参考 1 前言 关于使用python读写ply的比较清楚的教程很少 自己也是新手 摸索中 2 PLY
  • linux虚拟机重启后,运行nmtui提示NetworkManaer 未运行

    环境 centOS 8 虚拟机重启后 输入ifconfig 发现网卡丢失 1 重启NetworkManaer systemctl start NetworkManager 2 输入nmtui nmtui 编辑连接 笔者网络小白 只会用自动
  • 雅特力AT32F403A, 国产芯片PIN TO PIN 替代STM32F103

    中美贸易摩擦日渐加剧 美国从各个方面到处打压中国 半导体行业也收到一定冲击 逼迫国内企业不得不准备产品国产化方案 自从华为被美国制裁之后 国内的很多手机厂商明白了一个道理 爹有娘有 不如自己有 于是各大厂商纷纷走上了芯片国产化的道路 意法半
  • java Hashtable及其子类Properties 源码分析(通俗易懂)

    目录 一 前言 二 Hashtable详解 1 简介 2 特点 3 底层实现 4 HashMap VS Hashtable 三 Properties详解 1 简介 2 特点 3 具体使用 可以不看 四 完结撒 一 前言 大家好 本篇博文是对