HashMap结构

本文详细介绍了HashMap在Java 1.7和1.8中的结构变化,从数组+单链表到数组+链表+红黑树,探讨了负载因子0.75的原因以及容量必须为2的幂的考量。同时,讨论了HashMap的哈希计算方法,并指出在多线程环境下使用ConcurrentHashMap以确保线程安全。

HashMap结构及版本区别

1、HashMap:

继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。

是散列分布存储的,通过key/value结构实现。其中key和value都可以是null,是无序的。

2、HashMap的结构

2.1、jdk1.7采用 数组+ 单链表的数据结构

hashMap 在1.7的结构

hash表是一个数组,根据索引将条目存入hash表中,如果出现hash索引相同的时候,将会以链表的形式在同一个索引处储存多个条目,后来的条目存在在链表最后边(头插法)。

【什么是hashmap头插法:https://blog.youkuaiyun.com/styhm/article/details/111212508

2.2、jdk1.8后,HashMap的结构是数组+链表+红黑树

从JAVA 7中得知,在查找元素时候,可以根据hash值快速定位到数组具体的下标,但是后面的操作需要顺着链表一个一个的比较下去才能找到所需值,时间复杂度取决于链表的长度,为O(n),为了降低这一部分处理的开销,在JAVA 8中,当链表中的元素超过8个之后,会将链表转换为红黑树,在这些位置进行查找的时候可降低时间复杂度 为O(logn)。当红黑树节点数小于6就会变成链表。

3、HashMap 初始容量与加载因子。

当HashMap实例化时会涉及初始化容量,初始化容量默认是16.


/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 16;// 默认初始容量为16,必须为2的幂

当hash表中的条目数超过 容量 * 加载因子时,通过调用 rehash 方法(resize)将容量翻倍。

其中需要注意的是容量设置必须是2的整数次幂。那么为什么,必须是2的整数次幂呢?

hashmap中默认加载因子0.75

    /**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

为什么加载因子默认是0.75,而不是1呢,这要从空间(hash容量)和时间(存入是否发生碰撞,取是否需要遍历链表)两个方面综合评价。从而得出的一个较为调优的值0.75

4、hashMap的hash是怎么计算的

hashmap怎么将给加入进来的元素散列分布在table表的各个位置的呢

参考文章https://blog.youkuaiyun.com/styhm/article/details/109778522

5、线程安全问题

https://blog.youkuaiyun.com/styhm/article/details/111227027

线程安全的HashMap可以用代替

ConcurrentHashMap map = new ConcurrentHashMap(32);

 

A hash map, also known as a hash table, is a data structure that implements an associative array abstract data type, which can map keys to values. It uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found[^1]. In terms of implementation, let's consider the example provided in reference [1], where a `HashTable` class was defined. This class utilizes a `_hash()` method that computes a hash code for a given key using Python's built-in `hash()` function. The computed hash code determines the index within the underlying array where the key-value pair will be stored. To handle collisions—when two different keys produce the same hash code—this implementation uses chaining, meaning each bucket contains a collection of entries that share the same hash index. For Java and Python implementations, while specifics may vary, both languages provide their own optimized versions of hash maps. In Java, the `HashMap` class is part of the Java Collections Framework and provides methods for adding, removing, and retrieving elements based on keys. Similarly, Python’s built-in `dict` type serves as a highly optimized hash table, offering efficient access to items via keys. Here is a simplified version of how one might implement a basic hash map in Python: ```python class HashTable: def __init__(self): self.size = 10 self.table = [[] for _ in range(self.size)] def _hash(self, key): return hash(key) % self.size def add(self, key, value): bucket = self._hash(key) for i, (k, v) in enumerate(self.table[bucket]): if k == key: self.table[bucket][i] = (key, value) return self.table[bucket].append((key, value)) def get(self, key): bucket = self._hash(key) for k, v in self.table[bucket]: if k == key: return v return None def remove(self, key): bucket = self._hash(key) for i, (k, v) in enumerate(self.table[bucket]): if k == key: del self.table[bucket][i] return def __len__(self): return sum(len(bucket) for bucket in self.table) ``` This code defines a `HashTable` class with methods to add, retrieve, and remove key-value pairs. The `_hash` method calculates the index for storing these pairs, and the `__len__` method returns the total number of entries across all buckets. The `add` method checks if the key already exists in the corresponding bucket; if so, it updates the value. If not, it appends the new key-value pair to the bucket. The `get` method searches for the key in the appropriate bucket and returns its associated value, or `None` if the key does not exist. The `remove` method deletes the key-value pair if the key exists in the correct bucket. Both Java and Python offer more sophisticated internal mechanisms to manage resizing, load factors, and collision resolution strategies, but this example illustrates the fundamental principles behind hash map implementations.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值