Java容器源码分析—HashTable

概述

本文主要参考了Java Collection Framework 源码剖析这位博主的专栏,写的很好,感兴趣的可以去看一下!

HashTable底层实现都是一个链表数组,具有寻址容易、插入和删除也容易的特性;
事实上,HashMap几乎可以等价于Hashtable,除了HashMap是非线程安全的并且可以接受null键和null值。


HashTable在JDK中的定义

Hashtable实现了Map接口,并继承Dictionary抽象类 :

Hashtable也包括五个成员变量,分别是table数组、Hashtable中Entry个数count、Hashtable的阈值threshold、Hashtable的负载因子loadFactor 和 Hashtable结构性修改次数modCount

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {
    
     private transient Entry[] table;   // 由Entry对象组成的链表数组

	 private transient int count;   // Hashtable中Entry对象的个数

	 private int threshold;   // Hashtable进行扩容的阈值

 	 private float loadFactor;   // 在其容量自动增加之前可以达到多满的一种尺度,默认为0.75
 	 private transient int modCount = 0;   // 记录Hashtable生命周期中结构性修改的次数
}

HashTable数据结构

HashTable本质上是一个链表数组
HashTable
从上图中,我们可以形象地看出Hashtable底层实现还是数组,只是数组中存放的元素是Entry对象,而Entry对象是一种典型链状结构,定义如下:

static class Entry<K,V> implements Map.Entry<K,V> {

    K key;     // 键值对的键
    V value;        // 键值对的值
    Entry<K,V> next;     // 指向下一个节点的指针
    int hash;     // key 的哈希值(与HashMap中key的哈希值计算方式不同)

    /**
     * Creates new entry.
     */
    protected Entry(int h, K k, V v, Entry<K,V> n) {     // Entry 的构造函数
        value = v;
        next = n;
        key = k;
        hash = h;
    }

    ......

}

HashTable的快速存取

1、put(key,value)

HashTable保存数据和HashMap类似,计算key的hash值并且确定K/V对应要插入的桶位;其次查找该桶位内是否存在具有相同的key的K/V对,若存在直接覆盖对应的value值,否则将该节点保存在桶的链表的头位置(最先保存的元素放在尾部),如果容器达到阈值就会扩容;

public synchronized V put(K key, V value) {     // 加锁同步,保证Hashtable的线程安全性
        // Make sure the value is not null
        if (value == null) {      // 不同于HashMap,Hashtable不允许空的value
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry tab[] = table;
        int hash = key.hashCode();   // key 的哈希值,同时也暗示Hashtable不同于HashMap,其不允许空的key
        int index = (hash & 0x7FFFFFFF) % tab.length;   // 取余计算节点存放桶位,0x7FFFFFFF 是最大的int型数的二进制表示
        // 先查找Hashtable上述桶位中是否包含具有相同Key的K/V对
        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;
            }
        }

        // 向Hashtable中插入目标K/V对
        modCount++;     // 发生结构性改变,modCount加1
        if (count >= threshold) {    //在插入目标K/V对前,先检查是否需要扩容(不同于HashMap的插入后检查是否需要扩容) 
            // Rehash the table if the threshold is exceeded
            rehash();

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;   // 扩容后,重新计算K/V对插入的桶位
        }

        // Creates the new entry.
        Entry<K, V> e = tab[index];
        tab[index] = new Entry<K, V>(hash, key, value, e); // 将K/V对链入对应桶中链表,并成为头结点
        count++;     // Hashtable中Entry数目加1
        return null;
    }
  • HashTable不允许key为null,也不允许value为null;
  • HashTable中用于定位桶位的Key的Hash计算过程比HashMap要简单,直接;
  • HashTable则是先检查是否需要扩容后插入,与HashMap相反;
  • HashTable的put操作是线程安全的;

2、get(Object key)

Hashtable只需通过key的hash值定位到table数组的某个特定的桶,然后查找并返回该key对应的value即可;

    public synchronized V get(Object key) {    // 不同于HashMap,Hashtable的读取操作是同步的
        Entry tab[] = table;
        int hash = key.hashCode();   
        int index = (hash & 0x7FFFFFFF) % tab.length;   // 定位K/V对的桶位
        for (Entry<K, V> e = tab[index]; e != null; e = e.next) {   // 在特定桶中依次查找指定Key的K/V对
            if ((e.hash == hash) && e.key.equals(key)) {
                return e.value;       
            }
        }
        return null;   // 查找失败
    }

  1. HashTable的读取操作是同步的;
  2. HashTable中若读取到的Value值是NULL,只有一种可能就是HashTable中不含有该key的Entry;HashTable中不允许空的key,也不允许空的value;

HashMap、HashTable与ConcurrentMap的联系和区别

1、Hashtable与HashMap的联系和区别

  1. HashMap和Hashtable的实现模板不同:虽然二者都实现了Map接口,但HashTable继承于Dictionary类,而HashMap是继承于AbstractMap;Dictionary是是任何可将键映射到相应值的类的抽象父类,而AbstractMap是基于Map接口的骨干实现,它以最大限度地减少实现此接口所需的工作;
  2. HashMap和Hashtable对键值的限制不同:HashMap可以允许存在一个为null的key和任意个为null的value,但是HashTable中的key和value都不允许为null;
  3. HashMap和Hashtable的线程安全性不同:Hashtable的方法是同步的,实现线程安全的Map;而HashMap的方法不是同步的,是Map的非线程安全实现;
  4. HashMap和Hashtable的地位不同:在并发环境下,Hashtable虽然是线程安全的,但是我们一般不推荐使用它,因为有比它更高效、更好的选择ConcurrentHashMap;而单线程环境下,HashMap拥有比Hashtable更高的效率(Hashtable的操作都是同步的,导致效率低下)

2、Hashtable与ConcurrentHashMap的联系和区别

Hashtable和ConcurrentHashMap都可以用于并发环境,但是HashTable的性能不如ConcurrentHashMap;ConcurrentHashMap引入了分段锁机制,HashTable则会锁定整个map;

HashTable(同一把锁):采用synchronized来保证线程安全,效率低下。当多线程访问同步方法,会进入阻塞或者轮询状态,例如一个线程使用put操作,另一个线程不能使用put也不能使用get,导致效率低下;

ConcurrentHashMap(分段锁):每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。Segment 是一种可重入锁ReentrantLock,扮演锁的角色。HashEntry 用于存储键值对数据。

一个ConcurrentHashMap 里包含一个Segment 数组。Segment 的结构和Hashmap类似,是一种数组和链表结构,一个Segment 包含一个HashEntry 数组,每个HashEntry是一个链表结构的元素,每个Segment 守护着一个HashEntry 数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得对应的Segment。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值