Java常见的底层数据结构,一HashMap的分析为例子

 

首先:数据结构中有 “数组”和 “链表”两种基本的数据结构.算法

数组:存储区间是连续的,占用内存空间比较大。查询的时候比较方便,增长或者删除的时候比较缓慢;数组

链表:存储区间是离散的,占用内存空间比较小。增长或者删除的时候比较方便,查询的时候比较缓慢;数据结构

哈希表:结合数组和链表的优势。哈希表的实现由不少种的方法。下面是最为常见的“拉链法”;this

在一个长度为16的数组中,每一个元素存储的是一个链表的头结点。通常状况是经过hash(key)%len得到,也就是元素的key的哈希值对数组长度取模获得。好比上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。因此十二、2八、108以及140都存储在数组下标为12的位置。排序

-----------------------------------------------------------------------------------------------------接口

上述是最为常见的三种数据结构:内存

其中List中有LinkedList,ArrayList,Vector .List是有序的,元素能够重复的。源码

--------------------List--------------------------------------------------------------------------------hash

比较经常使用的是ArrayList和LinkedList.table

其中ArrayList的底层结构为数组:利于查询,不利于增长或者删除操做;

LinkedList的底层结构为链表:利于增长或者删除操做,不利于查询。

--------------------Set--------------------------------------------------------------------------------

Set经常使用的为HashSet和TreeSet. Set是无序的,元素不能够重复的。其中TreeSet在插入元素的时候,有天然排序和本身设置顺序。

其中HashSet利用哈希算法来存取元素。

TreeSet底层为二叉树的结构。

--------------------Map-------------------------------------------------------------------------

Map经常使用的为HashMap和TreeMap.

1.HashMap是基于哈希表的Ma接口实现的,以key-value的形式存在。HashMap的底层结构为“哈希表”。每次建立HashMap的时候就会初始化一个table数组。table的数组中的元素类型为Entry节点。其中HashMap是如何实现存储数据的:

实现的源码为:

public V put(K key, V value) {
        //当key为null,调用putForNullKey方法,保存null与table第一个位置中,这是HashMap容许为null的缘由
        if (key == null)
            return putForNullKey(value);
        //计算key的hash值
        int hash = hash(key.hashCode());                  ------(1)
        //计算key hash 值在 table 数组中的位置
        int i = indexFor(hash, table.length);             ------(2)
        //从i出开始迭代 e,找到 key 保存的位置
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {
            Object k;
            //判断该条链上是否有hash值相同的(key相同)
            //若存在相同,则直接覆盖value,返回旧value
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;    //旧值 = 新值
                e.value = value;
                e.recordAccess(this);
                return oldValue;     //返回旧值
            }
        }
        //修改次数增长1
        modCount++;
        //将key、value添加至i位置处
        addEntry(hash, key, value, i);
        return null;
    }

首先判断key值是否为空,若是不为空的话,计算key的哈希值,根据哈希值来计算在table数组中的位置。而后迭代该位置上的链表连,判断该条链上是否有hash值相同的。;若是哈希值相同则覆盖之前的value,没有相同的hash值,则将key-value添加到该条链上(则将该节点插入该链表的链头)。

2.TreeMap:底层结构为二叉树。

相关文章
相关标签/搜索