Java集合——List

List

结构图

img

三者比较

ArrayListVectorLinkedList
数据结构数组数组链表
元素可重复可重复可重复
扩容1.5倍默认1倍扩容不需要
优点查询快查询快查询慢
缺点增删慢增删慢增删快
安全性不安全安全,但效率低不安全

ArrayList源码

继承关系

public class ArrayList<E> 
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. RandomAccess接口支持随机访问

  2. Serializable支持序列化

底层数据结构

//Obj类型的数组来存储数据
//transient修饰的变量不能被序列化
transient Object[] elementData;

主要属性

//默认容量
private static final int DEFAULT_CAPACITY = 10;
//空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//我们将其与 EMPTY_ELEMENTDATA 区分开来,以了解添加第一个元素时要膨胀多少
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//元素存储
transient Object[] elementData;
//元素数量
private int size;
//数组被修改的次数
protected transient int modCount = 0;

构造方法

//无参构造
public ArrayList() {
    //将数组初始化为空数组
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//指定容量的构造方法
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) { //参数大于0直接初始化数组
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        //EMPTY_ELEMENTDATA一个空数组对象
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        //小于0抛出异常
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    }
}
//按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表
public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[]
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

增加

//添加元素
public boolean add(E e) {
    //确保容量
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //尾插
    elementData[size++] = e;
    return true;
}
//在指定位置添加元素
public void add(int index, E element) {
    //位置合法性判断
    rangeCheckForAdd(index);
    //确保容量
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //将当前位置及之后的元素向后移动
    System.arraycopy(elementData, index, elementData, index + 1,size - index);
    //插入
    elementData[index] = element;
    size++;
}

扩容

private void grow(int minCapacity) {
    //获取数组容量
    int oldCapacity = elementData.length;
    //1.5倍扩容
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    //容量合法性判断
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    //数组元素放入新数组
    elementData = Arrays.copyOf(elementData, newCapacity);
}

删除

public E remove(int index) {
    //位置合法性判断
    rangeCheck(index);
    //数组操作数+1
    modCount++;
    //获取元素
    E oldValue = elementData(index);
    //数组更新
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //clear to let GC do its work
    elementData[--size] = null;
    return oldValue;
}

LinkedList源码

继承关系

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  1. Serializable支持序列化

  2. 实现Dqueue接口可以作为队列使用

主要属性

//元素个数
transient int size = 0;
//头节点
transient Node<E> first;
//尾节点
transient Node<E> last;
//此列表在结构上被修改的次数。结构修改是那些改变列表大小的修改,或者以其他方式扰乱它,以致正在进行的迭代可能会产生不正确的结果。如果实现不希望提供快速失败的迭代器,则可以忽略此字段.
protected transient int modCount = 0;

底层数据结构

//用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;
    }
}

构造方法

//无参构造函数
public LinkedList() { }
//按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

增加

//头插法
private void linkFirst(E e) {
    //获取头节点
    final Node<E> f = first;
    //new新节点
    final Node<E> newNode = new Node<>(null, e, f);
    //更新头节点
    first = newNode;
    //更新前驱后继
    if (f == null)
        last = newNode;
    else
        //将原来的头节点挂在新的头节点上
        f.prev = newNode;
    size++;
    modCount++;
}
//尾插法
void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        //将新节点挂在原来的尾巴节点上
        l.next = newNode;
    size++;
    modCount++;
}

删除

//头删
private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    first = next;
    if (next == null)
        last = null;
    else
        next.prev = null;
    size--;
    modCount++;
    return element;
}
//尾删
private E unlinkLast(Node<E> l) {
    // assert l == last && l != null;
    final E element = l.item;
    final Node<E> prev = l.prev;
    l.item = null;
    l.prev = null; // help GC
    last = prev;
    if (prev == null)
        first = null;
    else
        prev.next = null;
    size--;
    modCount++;
    return element;
}

Vector源码

继承关系

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. RandomAccess接口支持随机访问

  2. Serializable支持序列化

主要属性

//存储数组 
protected Object[] elementData;
//元素数量
protected int elementCount;
//增加容量
protected int capacityIncrement;

底层数据结构

//Obj类型的数组来存储数据
protected Object[] elementData;

构造方法

//指定容量和扩容时的增量
public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}
//指定容量
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}
//无参构造
public Vector() {
    this(10);
}
//按照集合的迭代器返回的顺序构造一个包含指定集合元素的向量
public Vector(Collection<? extends E> c) {
    elementData = c.toArray();
    elementCount = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if (elementData.getClass() != Object[].class)
        elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

增加

//通过synchronized保证安全性
public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}

扩容

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

删除

//通过synchronized保证安全性
public synchronized boolean removeElement(Object obj) {
    modCount++;
    int i = indexOf(obj);
    if (i >= 0) {
        removeElementAt(i);
        return true;
    }
    return false;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值