【JAVA学习之路 | 进阶篇】ArrayList,Vector,LinkedList内存解析

1.ArrayList

(1). 特点 : 

  • 实现了List接口,存储有序的,可重复的数据.
  • 底层使用Object[]数组存储.
  • 线程不安全.(底层方法未用synchronized修饰.)

(2). 版本解析 : 

: JDK7版本

ArrayList list =new ArrayList<>();

//底层会初始化数组,直接new了一个长度为10的数组

Object[] elementData =new Object[10];

list.add("AA")//elementData[0] ="AA";

list.add("BB")//elementData[1] ="BB";

......

当添加第11个元素时,底层的elementData数组已满,则需要扩容.扩容为原来数组长度的1.5倍.并将原来的数组的内容copy到新创建的数组中.


JDK8版本

ArrayList list =new ArrayList<>();

//底层也会初始化数组,但该数组的长度为0

Object[] elementData =new Object[]{};

list.add("AA");//首次添加元素时,会初始化数组 : elementData =new Object[10];并elementData[0] ="AA";

list.add("BB");//elementData[1] ="BB".

当添加到11个元素时,底层数组已满,需要数组扩容,同样扩容至原来数组长度的1.5倍.并将原来数组的内容copy到新new出来的数组中.

小结 :

JDK7版本有点类似于饿汉式,一上来直接new长度为10的数组.

JDK8版本有点类似于懒汉式,创建ArrayList对象时new了一个长度为0的数组,当需要添加元素时,才new一个长度为10的数组.

2.Vector(JDK8版本)

Vector vector =new Vector<>();

//底层初始化数组,长度为10;

Object[] elementData =new Object[10];

vector.add("AA");//elementData[0] ="AA"

vector.add("BB");//elementData[1] ="BB"

当添加到第11个元素时,数组已满,需要扩容.扩容至原来数组长度的两倍大小.并将原来的数组的内容copy到新new出来的数组.

3.LinkedList(链表)

(1). 特点

  • 实现了List接口,可存储有序的,可重复的数据.
  • 底层使用双向链表存储.

(2). 解析

LinkedList list =new LinkedList<>();

//底层没做什么.

list.add("AA");//将"AA"封装到一个Node对象1中,list对象的属性first,last(类型Node)都指向了该Node对象(first,last分别为指向链表的头结点的指针和尾结点的指针).

list.add("BB");//将"BB"封装到一个Node对象2中,并将last指针指向了Node对象2,Node对象里有属性(Node prev, E item, Node next),并将node1.next =node2,node2.prev =node1.构成了双向链表.

4.建议

(1). Vector基本上已经不使用了.被版本抛弃了.

(2). ArrayList底层使用Object[]数组结构.查找与尾部添加的时间复杂度为O(1);而删除与插入的时间复杂度为O(n).

(3). LinkedList底层使用双向链表存储.查找与尾部添加的时间复杂度为O(n);而删除与插入的时间复杂度为O(1).

(4). 在选择了ArrayList的前提下,重载构造器ArrayList list1 =new ArrayList();

//底层创建了长度为10的数组

ArrayList list2 =new ArrayList(int capacity)

//底层创建了长度为capacity的数组.

你可能感兴趣的:(java,开发语言)