`

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源码深度剖析,面试必备

    JavaLinkedHashMap源码解析Java开发Ja

    6. **源码解析**: - `LinkedHashMap` 的核心是 `Entry` 类,它继承自 `HashMap` 的 `Node` 类,额外维护了前后节点的引用。 - `putEntryAt()` 和 `createEntryAt()` 方法负责在链表的正确位置插入新的节点。 - `...

    手写HashMap源码.rar

    《手写HashMap源码解析——深入理解数据结构与算法》 HashMap是Java编程语言中一个常用的集合类,它提供了一种高效、灵活的键值对存储方式。在面试过程中,尤其是2020年及以后的技术面试中,深入理解HashMap的实现...

    Java源码解析HashMap简介

    Java源码解析HashMap简介 HashMap是Java开发中最常用的集合之一,它基于hash表的实现,提供了map的所有可选操作,并且允许null值和一个null的key。HashMap的实现提供了常量级的性能,假设hash函数把元素们比较好的...

    Java源码解析——看优秀源码最能使人进步

    Java源码解析——看优秀源码最能使人进步 Java源码解析是一种深入了解JDK源码的方式,适合那些想深入了解JDK源码的人。通过对JDK源码的解析,可以让开发者更好地理解Java语言的底层逻辑,从而写出更加高效、稳定的...

    源码解析jdk8.0集合:HashMap的底层实现原理.pdf

    HashMap是Java集合框架的一部分,它实现了Map接口,用于存储键值对。其核心特点在于基于哈希表的映射机制,能够通过键快速检索对应的值。HashMap支持键和值为null,同时是非线程安全的,即其方法不是同步的。 2. ...

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

    Java源码解析HashMap的keySet()方法 Java中的HashMap提供了一个keySet()方法,该方法用于获取HashMap中的key的集合。下面我们将对HashMap的keySet()方法进行源码解析,以了解其内部实现机制。 首先,看一下keySet...

    Java解析JSON源码

    Java解析JSON源码是Java开发中的重要一环,因为JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,广泛应用于服务器与客户端之间的数据传输。本文将深入探讨如何在Java中解析JSON源码,以及如何利用...

    HashMap 源码分析

    《HashMap 源码解析——JDK11版本》 HashMap是Java中广泛使用的非同步散列表,其设计和实现是高效且灵活的。在JDK1.8之前,HashMap的底层数据结构采用的是数组+链表的方式,这种方式称为“拉链法”来解决哈希冲突。...

    深入理解Java之HashMap源码剖析

    深入理解Java中的HashMap源码,有助于我们更好地掌握这个常用数据结构的工作原理。HashMap是Java集合框架的重要组成部分,它实现了Map接口,提供了一种快速查找、插入和删除元素的方式。本文将详细解析HashMap的内部...

    Java源码解析HashMap的tableSizeFor函数

    在Java编程语言中,HashMap是一种常用的散列表数据结构,它提供了高效的插入、删除和查找操作。HashMap的容量(Capacity)是存储元素的槽位数量,它必须是2的幂,如16、32、64等。这是因为HashMap使用了开放寻址法或...

    java源码文档src

    源码解析可以帮助我们理解这些数据结构的内部实现,优化数据存储和操作。 8. **网络编程** `java.net`包包含了网络编程的相关类,如`Socket`、`ServerSocket`,以及URL和URI处理。源码分析有助于开发者理解TCP/IP...

    Java源码解析HashMap的resize函数

    Java源码解析HashMap的resize函数 HashMap的resize函数是Java中HashMap实现的关键部分之一,该函数用于对HashMap初始化或者扩容。下面将详细解析该函数的实现机理和源码。 resize函数的作用 resize函数的主要作用...

    java7hashmap源码-learn-java-source:学习java源码,java1.8

    《深入解析Java 7 HashMap源码》 HashMap作为Java集合框架中的重要成员,一直以来都是面试和技术探讨的热点。本文将详细剖析Java 7版本HashMap的内部实现机制,帮助读者理解其核心原理,提升对Java并发集合、数据...

    Java源码解析HashMap成员变量

    成员变量,是一个`Node,V&gt;[]`类型的数组。`Node`是HashMap自定义的内部类,用来存储键值对。数组的默认长度是`DEFAULT_INITIAL_...理解这些参数及其背后的设计原理,对于编写高效、稳定的Java代码是非常重要的。

    javahashmap源码-java_HashMap_jdk1.7:我的hashmap

    《深入解析Java HashMap在JDK 1.7中的实现细节》 HashMap是Java集合框架中的重要组成部分,它提供了一种高效、灵活的键值对存储方式。在JDK 1.7版本中,HashMap的实现机制有着独特的设计,本文将详细剖析其内部的...

    java7hashmap源码-mumble:咕哝

    《深入解析Java 7 HashMap源码》 HashMap作为Java集合框架中的重要成员,一直以来都是面试与实际开发中的热点话题。本文将深入剖析Java 7版本的HashMap源码,揭示其内部实现机制,帮助读者理解其高效性和潜在的并发...

    Java1.6源码

    `String`类是不可变字符串的实现,其源码解析可以帮助理解字符串的拼接、比较等操作。 2. **集合框架**:Java 1.6的集合框架在`java.util`包中,包括`List`、`Set`、`Map`接口及其实现类如`ArrayList`、`LinkedList...

Global site tag (gtag.js) - Google Analytics