List接口及其实现类

1:List接口常用实现类的对比

 1.1:
  ArrayList:作为List接口的主要实现类;线程不安全,效率高;底层使用Object[ ] elementData 存储。
  LinkedList:对于频繁的插入、删除操作,使用此效率比ArrayList高;因为其底层使用双向链表存储。
  Vector:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[ ] elementData 存储。
 1.2:ArrayList、LinkedList、Vector三者的相同点:
  以上三个类都实现了List接口,并且存储有序的,可重复的数据。

2:ArrayList源码分析

 2.1:Jdk7下源码分析:

  1)数组初始化机制

private transient Object[] elementData;	//底层数组名为  elementData
public ArrayList() {
	this(initialCapacity:10);	//调用本类的重写构造
}
public ArrayList(int initialCapacity) {
	super();
	//如果输入初始容量小于0,抛出异常
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
    //创建一个大小为initialCapacity的数组,也就是长度为的数组
    this.elementData = new Object[initialCapacity];
}

  2)add方法底层源码

public boolean add(E e) {
	//调用ensureCapacityInternal()方法
	ensureCapacityInternal(size + 1); 
	//将元素e赋值给elementData[size] 然后size++
	elementData[size++] = e;
	return true;
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;//快速失败机制
    //如果当前插入后的容量比数组长度大,调用grow方法进行扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);  
}
//grow()方法进行扩容
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)//MAX_ARRAY_SIZE这个值不是整形的最大值,而是数组的最大容量。
        newCapacity = hugeCapacity(minCapacity);//把最大值赋给newCapacity
        //数组扩容
    elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
	//异常处理
    if (minCapacity < 0)
        throw new OutOfMemoryError();
    //如果数组容量超过最大数组容量,返回整型的最大值,否则返回最大数组容量
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

  建议开发中使用带有参数的构造器:List list = new ArrayList(50);

 2.2:JDK8下源码分析:

  与JDK7下的源码进行对比,JDK下的变化:
  ArrayList lise = new ArrayList(); //底层Object[ ] elementData初始化为{},并没有创建长度为10的数组。list.add(123) 而当第一次调用add()时,底层才创建了长度为10的数组,并将数据123 添加到elementData[ ]中。
后续的添加和扩容操作与JDK7无异。都是使用 grow() 方法进行扩容。

3:LinkedList源码分析

  LinkedList list = new LinkedList():内部声明了Node类型的first和lst属性,默认值为null,list.add(123) //将123封装到Node中,创建了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;
        }
    }

双向链表添加元素具体操作(尾插)

	void linkLast(E e){
		final Node<E> l = last;
		final Node<E> newNode = new Node<>(l, e, next:null );
		last = newNode;
		if(l == null)
			first = newNode;
		else
			l.next = newNode;
		size++;
		modCount++;
	}

4:Vector源码分析

在Vector中,JDK7和JDK8中通过Vector()构造器创建对象时,底层创建了一个长度为10的数组,在扩容方面,区别于ArrayList,默认扩容为原来的数组长度的2倍。

private void grow(int minCapacity) {
	
	//原Vector容量值
    int oldCapacity = elementData.length;
    //如果有给capacityIncrement设置增长系数的话,就加上该系数值来扩容,否则将原先的数组容量变为2*oldCapacity
    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);
}

5:List接口中的常用方法

1)void add(int index, Object ele):在index位置插入ele元素

2)boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来

3)Object get(int index):获取指定index位置的元素

4)int indexOf(Object obj):返回obj在集合中首次出现的位置 ,如果没有就返回-1

5)int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置 ,如果没有就返回-1

6)Object remove(int index):移除指定index位置的元素,并返回此元素
相当于一个队列,因为remove()某个元素后,此元素后边的所有元素都会向前移动
注意:Collection中的remove是删除某个元素,这里是方法的重载而不是方法的重写 ,因为方法名一样,但形参类型不一样,在List中也可以按照对象去删除

7)Object set(int index, Object ele):设置指定index位置的元素为ele

8)List subList(int fromIndex, int toIndex):返回从[fromIndex到toIndex )位置的子集合,本身的list没有变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值