List、ArrayList、LinkedList、Vector

0.List

  • List是Collection的子接口,public interface List<E> extends Collection<E>,该接口依然使用了泛型技术
  • List里面的所有内容是允许重复的
  • 有序集合(也称为序列
  • 该接口可以精确控制列表中每个元素的插入位置。
  • 可以通过整数索引(列表中的位置)访问元素

List接口常用的实现类有如下:

ArrayList、Vector、LinkedList,其中ArrayList和Vector都是基于动态数组的实现,LinkedList是基于链表

1.ArrayList

ArrayList基于数组,动态扩容,增删慢,查找快

其中的属性包括如下:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
	private static final long serialVersionUID = 8683452581122892189L;
    private static final int DEFAULT_CAPACITY = 10;
    private static final Object[] EMPTY_ELEMENTDATA = {};
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    transient Object[] elementData; // non-private to simplify nested class access
    private int size; //所存储数据的个数而非容量
    
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
}

1.1 构造方法

  • ArrayList() 创建一个初始容量为10的空列表

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

    DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个长度为0的Object[],但为什么默认容量为10 ?因为在第一次使用时由于为容量为0,所以必定会扩容,而第一次扩容的长度为DEFAULT_CAPACITY

  • ArrayList(int initialCapacity) 创建一个初始容量为initialCapacity的空列表

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
    

    initialCapacity为负数时会报错

  • ArrayList(Collection<? extends E> c) 按照集合迭代器返回的顺序构造包含指定集合元素的列表

    public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();
        if ((size = a.length) != 0) {
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);	// ???
            }
        } else {
            // replace with empty array.
            elementData = EMPTY_ELEMENTDATA;
        }
    }
    

1.2添加元素(扩容)

当添加元素时,如果元素数量大于容量,则会发生扩容,容量增加到原来的1.5倍,部分源码实现;

public boolean add(E e) {	//添加一个元素到末尾
    modCount++;
    add(e, elementData, size);
    return true;
}
public boolean addAll(Collection<? extends E> c) {//添加Collection的所有元素
    Object[] a = c.toArray();
    modCount++;
    int numNew = a.length;
    if (numNew == 0)
        return false;
    Object[] elementData;
    final int s;
    if (numNew > (elementData = this.elementData).length - (s = size))
        elementData = grow(s + numNew);
    System.arraycopy(a, 0, elementData, s, numNew);
    size = s + numNew;
    return true;
}

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow(); //扩容,当size等于elementData的容量时,此时再添加元素会先扩容
    elementData[s] = e;
    size = s + 1;
}

private Object[] grow() {
    return grow(size + 1);
}

private Object[] grow(int minCapacity) { // minCapacity = size + 1;即容量最少加1
    //根据旧数组和新长度copy一个新数组,并将旧数组指向这个新数组;
    return elementData = Arrays.copyOf(elementData,
                                       newCapacity(minCapacity));
}

private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);	//增加旧容量的的0.5倍,即扩容1.5倍
    if (newCapacity - minCapacity <= 0) { //1.5倍扩容后,仍不满足或刚好满足容量最少加1
        //为空时,当第一次使用一个空的ArrayList时,会扩容DEFAULT_CAPACITY=10个容量
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    // private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE)
        ? Integer.MAX_VALUE
        : MAX_ARRAY_SIZE;
}
  1. 为什要使用MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 而不直接使用Integer.MAX_VALUE
    。。。
  2. 删除元素时是否会导致容量减少?
    不会自动减少,但可以用trimToSize(),将此 ArrayList实例的容量调整为列表的当前大小。。

1.3其他操作

public void	add (int index, E element)	//将指定元素插入此列表中的指定位置。
public boolean	add (E e)	//将指定的元素追加到此列表的末尾。
public boolean addAll (int index, Collection<? extends E> c)	//从指定位置开始,将指定集合中的所有元素插入此列表。
public boolean addAll (Collection<? extends E> c)	//将指定集合中的所有元素按指定集合的Iterator返回的顺序附加到此列表的末尾。

public E remove(int index) //删除并返回对应下标的元素
public boolean remove(Object o)  //删除指定元素
public boolean	removeAll (Collection<?> c)	//从此列表中删除指定集合中包含的所有元素。
public boolean	retainAll (Collection<?> c)	//仅保留此列表中包含在指定集合中的元素。
public void clear(){} //将所有元素置为null

public E get (int index) //返回此列表中指定位置的元素。
public int indexOf (Object o) //返回列表中第一次出现指定元素的索引,如果不包含该元素,返回-1。
public int lastIndexOf (Object o)	//返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1。
public boolean contains (Object o)	//如果此列表包含指定的元素,则返回 true
public List<E> subList (int fromIndex, int toIndex) //返回fromIndex(包含)和toIndex(不包括)之间的元素。
public boolean	isEmpty()	//如果此列表不包含任何元素,则返回 true 
    
public E set (int index, E element) //用指定的元素替换此列表中指定位置的元素。

public int	size()	//返回此列表中的元素数,即返回size。
    
public Iterator<E>	iterator()	//以适当的顺序返回此列表中元素的迭代器。
forEach用法
    
public void trimToSize() //将此 ArrayList实例的容量调整为列表的当前大小。
    
public Object clone() //返回此ArrayList实例的浅拷贝。
					//该clone()方法并不是ArrayList类中特定的方法。任何继承了CLonable接口的类都能够使用
  1. 深浅拷贝

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存, 所以如果其中一个对象改变了这个地址,就会影响到另一个对象

浅拷贝对应的就是深拷贝,深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

2.LinkedList

  • LinkedList是双向链表结构,增删快,查找慢

  • LinkedList 基于链表,故除List接口中的方法之外,还可以模拟实现栈、队列、双端队列的等数据结构的操作

变量和类型方法描述
voidaddFirst(E e)在此列表的开头插入指定的元素。
voidaddLast(E e)将指定的元素追加到此列表的末尾。
Eremove()检索并删除此列表的头部(第一个元素)。
EremoveFirst()从此列表中删除并返回第一个元素。
booleanremoveFirstOccurrence(Object o)删除此列表中第一次出现的指定元素(从头到尾遍历列表时)。
EremoveLast()从此列表中删除并返回最后一个元素。
booleanremoveLastOccurrence(Object o)删除此列表中最后一次出现的指定元素(从头到尾遍历列表时)。
Eget(int index)返回此列表中指定位置的元素。
EgetFirst()返回此列表中的第一个元素。
EgetLast()返回此列表中的最后一个元素。
booleanoffer(E e)将指定的元素添加为此列表的尾部(最后一个元素)。
booleanofferFirst(E e)在此列表的前面插入指定的元素。
booleanofferLast(E e)在此列表的末尾插入指定的元素。
Epop()弹出此列表所代表的堆栈中的元素,即弹出最后一个元素
voidpush(E e)将元素推送到此列表所表示的堆栈上, 即将元素添加到末尾

3.Vector

  • Vector相比于ArrayList是线程安全的,如果不需要线程安全实现,建议使用ArrayList代替Vector
  • Vector在新建对象时可以指定扩容增量
构造器描述
Vector()构造一个空向量,使其内部数据数组的大小为 10 ,其标准容量增量为零。
Vector(int initialCapacity)构造一个具有指定初始容量且容量增量等于零的空向量。
Vector(int initialCapacity, int capacityIncrement)构造具有指定初始容量和容量增量的空向量。
Vector(Collection<? extends E> c)按照集合的迭代器返回的顺序构造一个包含指定集合元素的向量。
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //扩容增量如果大于零,则增加对应的容量,否则容量翻倍
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    if (newCapacity - minCapacity <= 0) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值