List源码分析-List集合jdk1.7,1.8区别

List

​ Collection接口:单列集合,用来存储一个一个的对象

List接口:存储有序,可重复的数据

​ 1.ArrayList:list接口主要实现类,线程不安全,效率高,插入、删除麻烦,因为其它元素要前移后移

jdk7源码分析

Object[] elementData;//底层存储数据的结构

//空参构造器,initialCapacity-初始容量
//创建长度是10的Object[] 数组
public ArrayList(){
	this(initialCapacity:10);//调用有参构造方法
}
public ArrayList(int initialCapacity) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
}
public boolean add(E e) {
    //确保不会数组越界,要是容量不够,扩容
    ensureCapacityInternal(size + 1);  
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //oldCapacity >> 1左移一位,变成0.5倍,相当于扩容成1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

jdk8源码分析

public ArrayList() {
    //private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} 即让Object数组为{}空数组,用空参构造器初始化ArrayList时不像jdk7一样立即创建Object数组,有参构造器还是初始化创建数组
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //扩容也是1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity <= 0) {
        //单需要添加元素时才创建数组
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}
  • 当数组的大小大于初始容量的时候(比如初始为10,当添加第11个元素的时候),就会进行扩容,新的容量为旧的容量的1.5倍。

  • ArrayList在jdk7和jdk8区别,jdk7创建ArrayList就创建elementData数组,而jdk8在用无参构造器生成时使用时才创建Object数组,JDK1.7中的ArrayList对象的创建,类似于单例中的饿汉式;而JDK1.8,则类似于单例中的懒汉式。这么做的好处就是:延迟了数组的创建,节省内存空间

​ 2.LinkedList:底层使用双向链表储存,插入删除方便,检索不方便

/**
 * Pointer to first node.
 */
transient Node<E> first;

/**
 * Pointer to last node.
 */
transient Node<E> last;
//在LinkedList里面的静态内部类,链表节点
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;
    }
}

​ 3.vector:list接口的古老实现类;底层大量用了synchronized关键字,线程安全

  • vector的源码分析:jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。
  •  在扩容方面,如果创建时就设置了capacityIncrement(扩容因子的话)那每次扩容一倍扩容因子,没有设置扩容因子的话,默认扩容为原来的数组长度的2倍。扩容时机与ArrayList一致
    
Object[] elementData;//底层存储数据的结构

Vector 的所有方法加上了 synchronized 关键字,从而保证访问 vector 的任何方法都必须获得对象的 intrinsic lock (或叫 monitor lock ),也即,在vector内部,其所有方法不会被多线程所访问。

单个的方法 synchronized 了并不代表组合(compound)的方法调用具有原子性

虽然条件判断 if (!vector.contains(element))与方法调用 vector.add(element); 都是原子性的操作 (atomic),但在 if 条件判断为真后,那个用来访问vector.contains 方法的锁已经释放,在即将的 vector.add 方法调用 之间有间隙,在多线程环境中,完全有可能被其他线程获得 vector的 lock 并改变其状态, 此时当前线程的 vector.add(element); 正在等待(只不过我们不知道而已)。只有当其他线程释放了 vector 的 lock 后, vector.add(element); 继续,但此时它已经基于一个错误的假设了。

// Vector v = ...
    public  boolean putIfAbsent(E x) {
synchronized(v) {  
            boolean absent = !contains(x); 
            if (absent) { 
                add(x);
} 
}
        return absent; 
    }
 

所以,正确地回答那个“愚蠢”的问题是:
Vector 和 ArrayList 实现了同一接口 List, 但所有的 Vector 的方法都具有 synchronized 关键修饰。但对于复合操作,Vector 仍然需要进行同步处理。

三者共同点实现了List接口,存储有序,可重复的数据

(79条消息) Vector 是线程安全的?_xdonx的博客-CSDN博客_c++ 线程安全vector

纯手打不易,望点赞支持

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值