Java集合类ArrayList、LinkedList、vector、SynchronizedList详解

来源:互联网 发布:雪铁龙c5轮毂数据 编辑:程序博客网 时间:2024/06/09 22:43

集合类是Java中使用率比较高的类,平常总是会看源码,但看了又会忘记,今天专门记录一下,源码版本是JDK1.8的,本篇博客介绍的内容有ArrayList、LinkedList、Vetor、SynchronizedList、Set、Map

ArrayList

ArrayList可以理解为数组,平常的使用率很高

指定初始化容量大小

如果new的时候指定大小,那么按用户指定的大小进行初始化容量

未指定初始化容量大小

默认初始化大小

private static final int DEFAULT_CAPACITY = 10;

我们结合源代码来查看一下

public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}

被初始化时,赋值右边的是一个空的对象数组。如下,

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

看一眼add函数,看看在它内部到底发生了什么。

public boolean add(E e) {    ensureCapacityInternal(size + 1);  // Increments modCount!!    elementData[size++] = e;    return true;}

看到这里第一步调用一个方法,这里是在对容量做一个检查,我们去看一眼

private void ensureCapacityInternal(int minCapacity) {    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);    }    ensureExplicitCapacity(minCapacity);}

有没有看到第一行的话,elementData在默认初始化过程中被赋值为默认空对象数组,size的初值是0,所以这里会将其初始化为10

扩容策略

从代码中可以看出,容量扩充一半

int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);

LinkedList

与ArrayList相对应,这是一个链表。
链表的每一个子部分都是一个节点,也就是Node
下面是Node的结构,可见是一个双向的。

private static class Node<E> {    E item;    Node<E> next;    Node<E> prev;    Node(Node<E> prev, E element, Node<E> next) {        this.item = element;        this.next = next;        this.prev = prev;    }}

对于链表来说,它不需要初始化容量,每增加一个新的节点,只需要将其加在链尾即可,当然也可以选择加在链首,这由用户如何调用封装好的函数决定。JDK开发人员还为我们封装了许多方法,需要可以直接调用。

LinkedList与ArrayList对比

ArrayList LinkedList 中间添加/删除 效率低 查找 大部分情况下快,可以指定位置直接访问

Vector


Vector自JDK1.0开始就出现了。
与ArrayList相比,最大的特点就是更加安全,在添加删除等操作时,加上了synchronized关键字,保证了操作的同步性。

指定初始化容量大小,扩容策略

如果new的时候指定大小,那么按用户指定的大小进行初始化容量,并且用户可以指定扩容大小。
下面我们看一下扩容函数grow的内容

int oldCapacity = elementData.length;   int newCapacity = oldCapacity + ((capacityIncrement > 0 ?  capacityIncrement : oldCapacity);

这里的变量capacityIncrement是用户可以在显示初始化Vector对象时,用户设定 的一个扩容数,我们可以看一眼代码,

public Vector(int initialCapacity, int capacityIncrement)

我们可以看到这里是可以由用户指定的

未指定初始化容量大小

那么如果用户不去指定初始化容量的大小,初始化容量为10,默认会扩容为原容量的两倍。

在不需要保证同步性操作的情况下,普通的ArrayList即可满足需求。

SynchronizedList、Set、Map

在Collectiions类的下面有静态的线程安全的List、Set、Map内部静态类,我们来看看其中一个

public E get(int index) {        synchronized (mutex) {return list.get(index);}    }    public E set(int index, E element) {        synchronized (mutex) {return list.set(index, element);}    }    public void add(int index, E element) {        synchronized (mutex) {list.add(index, element);}    }    public E remove(int index) {        synchronized (mutex) {return list.remove(index);}    }

我们可以看到这里上是将所有的涉及到数据的操作,没贴出来的还有equals操作,都使用了synchronized代码块,显式地上锁,这里用户可以在获取时传入某对象锁,默认使用其本身。

0 0
原创粉丝点击