hashMap的底层数据结构:数组+链表
2017-08-10 10:04
239 查看
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在。在HashMap中,key-value总是会当做一个整体来处理,系统会根据hash算法来来计算key-value的存储位置,我们总是可以通过key快速地存、取value。
数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。
数组存储区间连续,占用内存比较严重,空间复杂度很大。但数组的二分查找时间复杂度小,为O(1);
数组的特点是:寻址容易,插入和删除困难;
链表存储区间离散,占用内存比较宽松,空间复杂度很小,但时间复杂度很大,达O(N)。
链表的特点是:寻址困难,插入和删除容易。
实际上hashMap是一个链表散列
那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。
哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。
哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法,我们可以理解为“链表的数组” ,如图:
哈希表是由数组+链表组成的,
HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢?这里HashMap有做一些处理。
首先HashMap里面实现一个静态内部类Entry,其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry[] table;
可参阅hashMap源码中
/**
* Basic hash bin node, used for most entries. (See below for
* TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
*/
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.ha
4000
shCode(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;
}
}
HashMap和Hashtable的底层实现都是数组+链表结构实现的,这点上完全一致
如果你想深入了解,参阅hashMap实现原理分析 http://blog.csdn.net/vking_wang/article/details/14166593
感谢万能的互联网,我是IT搬运工
数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。
数组
数组存储区间连续,占用内存比较严重,空间复杂度很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;
链表
链表存储区间离散,占用内存比较宽松,空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。
实际上hashMap是一个链表散列
哈希表
那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。
哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法,我们可以理解为“链表的数组” ,如图:
哈希表是由数组+链表组成的,
HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢?这里HashMap有做一些处理。
首先HashMap里面实现一个静态内部类Entry,其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry[] table;
可参阅hashMap源码中
/**
* Basic hash bin node, used for most entries. (See below for
* TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
*/
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.ha
4000
shCode(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;
}
}
HashMap和Hashtable的底层实现都是数组+链表结构实现的,这点上完全一致
如果你想深入了解,参阅hashMap实现原理分析 http://blog.csdn.net/vking_wang/article/details/14166593
感谢万能的互联网,我是IT搬运工
相关文章推荐
- 数组链表hashmap底层
- 107-109_容器_自己实现HashMap_Map底层实现_哈希算法实现_使用数组和链表
- Java集合,HashMap底层实现和原理(1.7数组+链表与1.8+的数组+链表+红黑树)
- hashmap数据结构 数组+链表
- HashMap集合源码以及底层结构解析(何时数组+单项链表变为数组+红黑二叉树)
- 每日一省之—使用线性探测法(仅利用数组作为底层数据结构)实现HashMap
- java 的HashMap底层数据结构
- 数据结构专项练习(数组、链表、二叉树)
- 栈实现(数据结构---数组,链表 C实现)
- 简单的数据结构(总结)只涉及用数组或链表实现
- java 的HashMap底层数据结构
- 深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用
- 【数据结构】动态数组,数组链表,双向链表
- HashMap的实现原理和底层数据结构
- 数据结构_数组与广义表_链表的递归遍历
- 数据结构学习---堆栈的动态数组实现及链表实现
- 深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用
- java面试之HashMap的实现原理和底层数据结构
- 常用的数据结构String、链表、Map、hashmap、hashtable区别
- 数据结构的选择-“数组、链表、树、哈希表”选哪个(性能比较)?