`

HashMap 源码分析

    博客分类:
  • Java
阅读更多

近几年HashMap是各大公司面试的热点,并由此延伸出非常多的东西,下面我们来讲解一些小知识点:

①HashMap的基本信息

②HashMap和HashTable的区别

③HashMap的底层实现

④HashMap解决碰撞问题

⑤ConcurrentHashMap的实现原理

 

一、HashMap的基本信息

       基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 HashMap是无序的线程非安全的。

 

二、HashMap和HashTable的区别

       ①HashMap是线程非安全的,HashTable是线程安全的。

       ②HashMap可以接受null值和null键,HashTable不接受。

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

       ④在单线程环境下,HashMap的速度比HashTable快,线程非安全的比线程安全的速度快,因为线程安全的存在一个加锁解锁的过程,当大量的这些过程累加到一块,是一个非常可观的时间。

       ⑤HashMap不能保证随着时间的推移元素的次序不发生变化。

 

三、HashMap的底层实现:

       HashMap在1.8之前底层是由Entry 数组和链表组成,1.8是由Entry数组、链表和红黑树组成;先来讲一下1.8之前的底层实现;



 HashMap采用 Entry 数组来存储,每一个键值对组成一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Entry实体,代码如下:

 

    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }

 1.8及之后加入了红黑树的概念,每当一个链表的长度大于8的时候,便自动转化为红黑树 ,结构如下图:

 



 HashMap按照key的hash值来计算Entry在HashMap中的储存位置的,当value值相同时候可以存在在不同的链表中去 ;

 

四、HashMap对HashCode碰撞的处理

       运用拉法来解决:HashCode是使用key通过hash函数计算出来的,由于不同的key,通过此函数可能会算出同样的HashCode,所以采用拉链法来解决冲突,把HashCode相同的 value连成链表,但是get的时候根据key又去桶里找,如果是在一个链表中说明是冲突的,此时还需要检测key是否相同;

       用拉链法解决问题的时候,在调用HashMap的put方法的时候,都会首先调用HashCode去查找相关的key,当有冲突的时候,在调用equals方法;

       当两个不同的键有相同的HashCode的时候,他们会存储在同一个 bucket位置的链表中,键对象的equals()来找到对应的键值对;

 

五、 ConcurrentHashMap的实现原理

        ConcurrentHashMap是线程安全且高效的HashMap,在并发程序中使用HashMap可能导致程序死循环,而使用线程安全的HashTable效率又非常低下。

        HashMap在并发执行put操作的时候会引起死循环,是因为多线程会导致HashMap的Entry链表形成环形数据结构,Entry的next节点永远不为空,就会产生死循环获取Entry;

       HashTable在多线程环境下,当一个线程访问HashTable的同步方法,其他线程也访问HashTable的时候,会进入阻塞或者轮询状态;

       ConcurrentHashMap是Segment数组结构和HashEntry数组结构构成,Segment是 一种可重入锁,在ConcurrentHashMap中扮演锁的角色,HashEntry则用于存储键值对数据:

结构图如下图所示:



 

ConcurrentHashMap使用 分段锁Segment来保护不同段的数据,每一把锁用于锁容器中的一部分数据,当多线程访问容器里面不同数据段的数据时,线程就不会存在锁竞争,,从而有效的提高并发访问效率。 

 

  • 大小: 3.5 KB
  • 大小: 8.6 KB
  • 大小: 5 KB
分享到:
评论

相关推荐

    HashMap源码分析

    HashMap 是 Java 中最常用的集合类之一,它是基于哈希表实现的,提供了高效的数据存取功能。HashMap 的核心原理是将键(key)通过哈希函数转化为数组索引,然后将键值对(key-value pair)存储在数组的对应位置。...

    1.面试必考之HashMap源码分析与实现 伸缩性角度看HashMap的不足

    1.面试必考之HashMap源码分析与实现 伸缩性角度看HashMap的不足

    面试必考之HashMap源码分析与实现

    面试中,HashMap的源码分析与实现是一个常见的考察点,因为它涉及到数据结构、并发处理和性能优化等多个核心领域。本篇文章将深入探讨HashMap的内部工作原理、关键特性以及其在实际应用中的考量因素。 HashMap基于...

    HashMap源码分析-思维导图.xmind

    hashmap的原理啊思想。

    HashMap源码分析系列-第四弹:HashMap多线程解决方案.docx

    #### 二、HashMap线程安全问题分析 在多线程环境中,`HashMap`的主要线程安全问题包括但不限于: 1. **链表死循环问题**:在JDK 1.7中,当多个线程同时进行`put`操作时,可能会出现链表死循环的情况,这是一个严重...

    Java集合系列之HashMap源码分析

    Java集合系列之HashMap源码分析 Java集合系列之HashMap源码分析是Java集合系列中的一篇非常重要的文章,它详细介绍了Java集合系列之HashMap源码,具有很高的参考价值。下面我们将对HashMap源码进行详细的分析。 ...

    hashmap实现原理

    哈希映射(HashMap)是Java编程语言中广泛使用的数据结构之一,主要提供键值对的存储和查找功能。HashMap的实现基于哈希表的概念,它通过计算对象的哈希码来快速定位数据,从而实现了O(1)的平均时间复杂度。在深入...

    Java高级面试第二套1.面试必考之HashMap源码分析与实现

    微信小程序详细图文教程 泉州大白网络科技 目录 一.微信小程序申请 二....1.申请服务器 2.部署服务器 3.域名申请和配置 三....一....申请,并认证(未认证不能发布,认证需要300元,目前只支持企业认证)详细见官网说明。...

    JAVA之hashmap源码分析-Mobile-Dev-Analysis:android或java的分析

    JAVA之hashmap源码分析 Mobile-Dev-Analysis Analysis of android or java 红岩网校工作站移动开发部学员分组学习 为了让大家学的更加坚固,采取小组学习的方式帮助大家学习,同时在学习研究的过程中需要不断的做...

    JAVA之hashmap源码分析-haha:已弃用的Java库可自动分析Android堆转储

    JAVA之hashmap源码分析 无头Android堆分析器 “哈哈!” -纳尔逊 此存储库已弃用 创建该项目的目的是通过重新打包其他存储库中的堆转储解析器来提供堆转储解析器。 LeakCanary现在有它自己的。 该解析器在Maven ...

    JAVA之hashmap源码分析-superword:Superword是一个Java开源项目,致力于英语单词分析和辅助阅读的研究

    JAVA之hashmap源码分析Superword是Java开源项目,致力于研究英语单词分析和辅助阅读,包括但不限于拼写相似度,定义相似度,发音相似度,拼写转换规则,前缀和动态前缀,后缀以及动态后缀,词根,复合词,文本辅助...

    【死磕Java集合】-集合源码分析.pdf

    四、HashMap源码分析 HashMap是一种基于散列表实现的Map,提供了快速的键值对存储和检索能力。HashMap的继承体系中,它继承了AbstractMap,实现了Map接口。 HashMap的主要属性包括键值对数组table、键值对个数size...

    Java面试专属视频

    面试必考之HashMap源码分析与实现 ,微服务架构之Spring Cloud Eureka 场景分析与实战,高性能必学之Mysql主从架构实践 ,架构师不得不知道的Spring事物不能回滚的深层次原因 ,分库分表之后分布式下如何保证ID全局...

    Android(Java) 模拟登录知乎并抓取用户信息

    在本文中,我们将深入探讨如何使用Java在Android平台上实现模拟登录知乎并抓取用户信息的过程。... 首先,我们需要了解的是Android的网络访问机制。Android系统为了安全性和用户体验,对网络访问进行了限制,必须在...

    HashMap源码剖析共10页.pdf.zip

    《HashMap源码剖析》 HashMap是Java编程语言中一个非常重要的数据结构,它在实际开发中被广泛应用。作为集合框架的一部分,HashMap实现了Map接口,提供了高效、非同步的键值对存储功能。在这个10页的PDF文档中,...

    手写HashMap源码.rar

    本篇文章将通过分析一个名为"MyHashMap"的手写HashMap源码,来探讨HashMap的内部机制,帮助提升编程能力。 首先,HashMap的核心是基于哈希表的数据结构,它利用键(Key)的哈希函数将键映射到数组的特定位置,从而...

Global site tag (gtag.js) - Google Analytics