常见集合类的底层原理

ArrayList

add方法的实现过程,考虑arraylist的扩容机制

elementData[size++]=e;//把加入的数据存储到elementData这个数组中.

ArrayList的成员属性

size的默认值0 数组下标从0开始
elementData[size++] elementData[1]=e;

数组的初始化方式:
1.1静态初始化
1.2动态初始化

观察一下扩容的方法:

grow(minCapacity)方法才是真正的扩容方法,它什么时候扩容尼

讲解的案例1:

new ArrayList();构造器内部的实现是

  1. new ArrayList对象的时候,如果没有指定默认的容器大小,那么容器大小为0

  2. 当new出的对象,执行第一次add方法的时候,可以发现,如果容器大小默认为0,那么取出最大值(缺省值)10,那么数组的容器大小变为10。

  3. 当存放的数据大于容器量时,进行扩容

原有的容器大小+原有容量大小向右移动一位,也就是很多程序员所说的近似1.5倍。

讲解的案例2:

new ArrayList(8);构造器内部的实现是

  1. 当存入的数量大于8的时候,才执行上面grow扩容方法,

ArrayList的底层是采用数组的方式进行实现的。数组特点:查询效率高,增删效率低。

Vector的实现原理
自己查看源代码

LinkeList实现原理

底层是采用链表的方式进行实现的,链表特点:增删效率高,查询效率低,克服数组创建指定大小的缺陷,充分利用内存。

添加数据的原理:

LikeLast(e);

在考虑节点指针 指向的问题。

HashMap底层原理

二叉树:
在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆
满二叉树:
一棵深度为k,且有2^k-1个节点的二叉树,特点:每一层上的节点数都是最大节点数。

什么是深度

每个深度最大的二叉树节点数量: 2 深度-1次幂
深度为k时,最多的二叉树的数量 2^K-1

扩展树序号(存储的结构模型):

完全二叉树:
若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树

平衡二叉树
(Balanced Binary Tree)
又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

红黑树
(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构.
完全自平衡的操作。

  1. HashMap的原理,内部数据结构?
    底层使用哈希表(数组+链表),当链表过长会将链表转成红黑树以实现O(logn)时间复杂度内查找.

2.讲一下HashMap中put方法过程?

  1. 对key求hash值,然后再计算下标
  2. 如果没有碰撞,直接放入桶中
  3. 如果碰撞了,以链表的方式链接到后面
  4. 如果链表长度超过阀值(TREEIFY_THRESHOLD==8),就把链表转成红黑树。
  5. 如果节点已经存在就替换旧值
  6. 如果桶满了(容量*加载因子),就需要resize.

Hashtable的实现原理

HashMap的源码
\成员属性:

内部类:

Node<K,V> 实现了Map.Entry<K,V>
属性理解:hash 值是节点存储的位置
K key 节点的key值
V value 值
Node<K,V> next;下一个节点的指针

加载因子:0.75f

HashMap的面试题
讲解put的实现过程

  1. .对key求hash值,然后再计算下标

Hash(key)

采用三目运算符处理的,如果key为null 那么hash值为0
如果不为null,那么key求出hashCode的值,然后对hashCode值进行移位得到的数字与原hashCode值进行异或。
高16为不变,低16位与高16位异或的结果位 后新低16位值。

hash函数的实现原理:高16bit不变,低16bit和高16bit做了一个异或

下标的计算方式:

首先要明白 hashmap底层是用数组+链表的实现,当链表过长会转换成红黑树。

数组初始化了没,没有,是null值
什么时候初始化,第一次put的时候初始化操作,它采用默认的初始化容量16,threshold值12 初始化容量*加载因子

  1. 数组下标的计算方式:
    (n - 1) & hash n代表数组的长度

  2. hashmap扩容机制:
    newCap = oldCap << 1

4.扩容之后新的位置怎么计算:
容量扩充为原来的两倍,然后对每个节点重新计算哈希值
这个值只可能在两个地方,一个是原下标的位置,另一种是在下标为《原下标+原容量》的位置.

Hashtable的底层实现原理
Hashtable的底层实现原理

put方法中,如果value为空 则抛出异常 Key value

对key求hashCode() key如果为空,也会抛出异常。
Hashtable与HashMap的区别
1.
Hashtable是线程安全
HashMap是非线程安全
2.
Hashtable不允许有null的value值,也不允许有null的key值,jdk1.0引入
HashMap允许有null的value和null的key值,jdk1.2

扩容机制不一样
下标计算方式不一样
Hash算法不一样
底层的实现原理
HashMap的底层实现原理

猜你喜欢

转载自blog.csdn.net/CSDN_bird/article/details/91410647