• Java HashMap和Hashtable的原理和区别


    1、概述:HashMap 基于哈希表<key,value>,实现Map接口,接受null的键和值,不允许重复的key,但允许重复的value,即不同的key可以对应相同的value值,非线程安全,Hashtable和HashMap非常类似,同样实现了Map接口,但是Hashtable不接受null的键和值,Hashtable是线程安全的,Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

    2、数据结构:数组和链表的结合。本身是一个数组,数组中的元素是链表。如图所示:

    数组中存储的是链表的头结点,元素存储到数组中的规则是:一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。

    HashMap和Hashtable里面有一个静态内部类Entry,其重要属性包括key,value,next,从这些属性就可以看出这是对键值对实现的一个基础bean,所以HashMap和Hashtable是一个线性数组Entry[]

    3、存数据

    键值对A,通过计算key的hash值得到index,则该元素存储在Entry[index],当有键值对B获得的index相同时,上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry,所以HashMap会这样做:B.next = A,Entry[index] = B,如果又进来C,index也相同,那么C.next = B,Entry[index] = C,数组中存储的是最后插入的元素(注:HashMap和Hashtable里面设置一个加载因子,随着map的size越来越大,Entry[]会根据加载因子以一定的规则加长长度。)

    4、取元素,先根据key值获取到键值对在数组中的下标,然后再遍历该下标处的链表。

    5、null key总是存放在Entry[]数组的第一个元素。

    6、HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。

    注:“快速失败”也就是fail-fast,它是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast机制。记住是有可能,而不是一定。例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。

  • 相关阅读:
    AS/400开发经验点滴(三)如何使用分布式关系数据库
    AS/400开发经验点滴(五)通用日志管理工具
    AS/400开发经验点滴(二)一个批量修改文件属性的工具
    FTP执行AS400命令
    ORA12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
    Centos 查看系统硬件信息
    [转]Oracle的DBMS_METADATA包
    java读写删.text,.xml文件内容
    oracle 是user_tables里面可以查找到一个表,而用DESC或者insert语句插入时就会报不存在视图。
    Oracle监听服务lsnrctl参数及查询状态详解
  • 原文地址:https://www.cnblogs.com/mingyao123/p/6907136.html
Copyright © 2020-2023  润新知