`

Java HashMap源码解析

阅读更多
1. HashMap内存储的元素是Entry,并且Entry是按照链表的形式来存储的。
transient Entry<K,V>[] table; // 用数组来存储,它的原理是每个数组的元素都是一个链表头



Entry的定义如下:
static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        int hash;
}


2. get(Object key)方法解读
    public V get(Object key) {
        // 对key进行判空
        if (key == null)
            return getForNullKey();
        // 根据key找Entry
        Entry<K,V> entry = getEntry(key);

        return null == entry ? null : entry.getValue();
    }


 final Entry<K,V> getEntry(Object key) {
        //计算hash值
        int hash = (key == null) ? 0 : hash(key);
        // 根据hash值来查找在数组中的下标位置,然后沿着链表进行查找
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }



3. put(key,value)方法解读
  public V put(K key, V value) {
        // 对key进行判空处理
        if (key == null)
            return putForNullKey(value);
        // 计算hash值
        int hash = hash(key);
        // 查找在数据中的位置,然后沿着链表查找 ,如果有相同的值就覆盖,没有就加一个entry
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }



4.常见的参数设置
  默认大小是16
 static final int DEFAULT_INITIAL_CAPACITY = 16;


  当容量超过16时,就会扩容,然后会重新计算hash值,所以尽量在初始化的时候指定大小。

5. hashmap vs hashtable
   1)hashmap 是允许存储空值的,然hashtable是不允许的;
   2)初始化的大小不一样,hashmap是16,hashtable是11;
   3)hash的计算公式是不一样的;
   4) hashtable是线程安全的,而hashmap不是线程安全的。hashtable是怎么来保证线程安
      全的呢?(有些人看了一些面试宝典之类的,只是记住了这个结论)
     
      // 使用synchronized 来实现线程安全的
      public synchronized V put(K key, V value) {
        // Make sure the value is not null(不能为空的)
        if (value == null) {
            throw new NullPointerException();
        }
        ..
      }
      
分享到:
评论

相关推荐

    HashMap源码深度剖析.md

    HashMap源码深度剖析,面试必备

    Java源码解析HashMap简介

    今天小编就为大家分享一篇关于Java源码解析HashMap简介,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    Java源码解析HashMap的tableSizeFor函数

    今天小编就为大家分享一篇关于Java源码解析HashMap的tableSizeFor函数,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    Java源码解析HashMap成员变量

    今天小编就为大家分享一篇关于Java源码解析HashMap成员变量,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    Java源码解析HashMap的keySet()方法

    今天小编就为大家分享一篇关于Java源码解析HashMap的keySet()方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    Java源码解析HashMap的resize函数

    今天小编就为大家分享一篇关于Java源码解析HashMap的resize函数,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    Java TreeMap 源码解析

    继上篇文章介绍完了HashMap,这篇文章开始介绍Map系列另一个比较重要的类TreeMap。 大家也许能感觉到,网络上介绍HashMap的文章比较多,但是介绍TreeMap反而...  implements NavigableMap, Cloneable, java.io.Seria

    java基础类型源码解析之多角度讲HashMap

    主要给大家介绍了关于java基础类型源码解析之HashMap的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java基具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

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

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

    集合类底层源码解析汇总

    java所有集合类底层源码解析汇总,包括ArrayList、HashMap、HashSet、LinkedList、TreeMap、HashSet、ConcurrentHashMap等集合框架的底层实现源码大白话解读。

    解析HashMap.md

    黑马程序员HashMap的笔记,面试必问,笔记很好,内容言简意赅,看完收获很多,希望能帮助大家的学习

    ConcurrentHashMap源码解析

    解析concurrenthashmap的源码,学习多线程的思想

    全面解析Java中的HashMap类

    HashMap类为Java提供了键值对应的map类型,本文将从源码角度全面解析Java中的HashMap类,同时包括其各种常用操作方法等,欢迎参考与借鉴

    java8集合源码分析-CollectionDemo:自己复习集合框架时候的例子

    集合源码分析 java基础复习 [TOC] 一、集合 1.Iterator 2.Collection 2.1 List---&gt;有序、有索引、元素可重复 1.ArrayList: 底层是数组结构、查询快、增删慢、不同步 添加第一个元素的时候,创建默认个数是10个,...

    java基础案例与开发详解案例源码全

    2.3.5 常见错误解析24 2.4 Java类库组织结构和文档27 2.5 Java虚拟机简介28 2.6 Java技术两种核心运行机制29 2.7 上机练习30 第3章 3.1 变量32 3.1.1 什么是变量32 3.1.2 为什么需要变量32 3.1.3 变量的声明和赋值33...

    LinkedHashMap 核心源码解析

    无序的 HashMap ,按 key 排序的 TreeMap ,那么 LinkedHashMap特点在哪呢 – 维护插入的顺序.LinkedHashMap 也同样出自于 Bloch之手(开发了整个 Java 集合框架的男人). 元素存储关系 红黄箭头:元素添加顺序 蓝...

    蚂蚁java架构师(第七/八期含项目) |课件完整|完结无秘

    08HashMap与ConcurrenthashMap源码解读 09MySQL深度原理解析 10Netty深度源码解读 11SpringCloud微服务框架源码解读 12彻底搞懂分布式锁架构设计原理 13分布式数据一致性设计原理 14分布式消息中间件 15实战新零售...

    JAVA高并发高性能高可用高扩展架构视频教程

    JAVA企业级基础课题(HashMap那些事) 企业架构师必备技能(JAVA核心技术反射) JavaWeb之基础(手写实现Tomcat服务器) java多线程编程 纯手写实现SpringIOC实现过程 JEE企业级开发(企业级项目开发权威指南) 网络爬虫之...

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    eclipsejava源码添加-automatic-java-logger:通过添加日志记录语句,使用EclipseJava抽象语法树(AST

    启动器负责解析,重写并使用返回的信息来创建已声明变量及其重新分配的HashMap。 启动器程序还自动执行所述Java程序的多次迭代,并从配置文件中提取不同的输入,并将日志记录语句写入文件中。 例子 以下是Logger的...

Global site tag (gtag.js) - Google Analytics