总结 数组在JDK中的应用

数据结构中的数组

从数据结构分类上数组是是一种物理的数据结构,常见的物理结构还是链表。数组的定义就是:有限个相同类型的元素的有序集合,其特点是内存一般空间顺序存储,随机访问效率高(根据索引获取元素),时间复杂度为O(1)。下面从时间复杂度上看数组中的增、删、查这个操作的时间复杂度;

  • 添加操作:O(n),这里O(n)是消耗在数组扩容上;
  • 删除操作:O(n),删除操作后需要挪动元素。
  • 读取操作:O(1),根据索引查询元素;
  • 更新操作:O(1),这里的更新是指更具指定索引进行更新。

Java中的数组

数组的基本用法
回到正题,笔者最近在看JDK1.8的源码,发下数组在底层有广泛的应用,因此用这篇文章记录数组的JDK源码进行了使用。因为数组的在定义时候就需要确定长度,那么数组往往伴随着个扩容的问题。本文也会对数组在不同类中的初始容量,扩容的时机(什么时候 出发扩容),扩容的机制(扩容后的容量为原来的多少倍)进行简单的记录,但是详细的扩容细节就不过多分析。

1.java.lang包

String

private final char value[]; //底层是用字符数组存放数据,而且用final修饰

AbstractStringBuilder

该类其实就是StringBuilder和StringBuffer的父类

char[] value; //底层也是用字符数组存储数组,但是这里不是用final修饰的

ThreadLocal.ThreadLocalMap

private Entry[] table; //数组存储不同的ThreadLocal的信息,Entry为key-value形式的哈希表
  1. 默认容量:16;
  2. 扩容时机:数组元素超过数组当前容量的三分之二;
  3. 扩容机制:扩容后的容量是原来容量的 2 倍;

2.java.util包

ArrayList

 transient Object[] elementData; //存放list元素的数组(transient不参与序列化的过程)
  1. 默认容量:10;
  2. 扩容时机:数组满的时候;
  3. 扩容机制:扩容后的容量是原来容量的 1.5 倍;

HashMap

    transient Node<K,V>[] table;  //存放数据的数组

Node类型可能为链表中节点或者红黑树的节点

  1. 默认容量:16;
  2. 扩容时机:当前结合中元素大于(数组当前容量*负载因子),负载因子是0.75。
  3. 扩容机制:为原来容量的两倍;

Hashtable

private transient Entry<?,?>[] table;

Entry是链表节点类型

  1. 默认容量:11;
  2. 扩容时机:当前结合中元素大于(数组当前容量*负载因子),负载因子是0.75。
  3. 扩容机制:为原来容量的两倍再加1;(HashMap是原来的两倍)

Vector

    protected Object[] elementData; //存储数据的元素
  1. 默认容量:10;
  2. 扩容时机:数组满的时候;
  3. 扩容机制:扩容后的容量是原来容量的 2 倍;(ArrayList是1.5倍数)

3.java.util.concurrent包

ArrayBlockingQueue

final Object[] items; //队列元素存放在该数组中,数组大小必须在初始化的时候赋值,没有默认值
  • 默认容量:没有默认容量,容量大小需要在构造实例时参数;
  • 扩容机制:该类是一个阻塞队列,不会有扩容的逻辑,当数组满的时候,就会阻塞添加操作或添加失败。

CopyOnWriteArrayList

 private transient volatile Object[] array; //底层也是基于数组,volatile修饰保证可见性
  • 默认容量:0
  • 扩容机制:添加元素时通过拷贝数组进行扩容,扩容后容量为原来的容量加上添加的元素的个数。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章