Java中List的简述

什么是 List

什么是集合

集合就是把具有相同属性的东西放在一起,也可以是容器,把有关的东西都放进去

什么是 List

List是位于java.util下的一个接口,有序集合(也称为序列)。此界面的用户可以精确控制每个元素在列表中的插入位置。用户可以通过整数索引(列表中的位置)访问元素,并在列表中搜索元素

List的继承、实现关系

其继承了Collection接口并由AbstractList来实现,Collection又继承了Iterable接口

  • Collection:集合层次结构中的根接口。一个集合表示一组对象,称为它的元素。一些集合允许重复元素,而另一些则不允许。有些是有序的,有些是无序的。
  • Iterable:实现此接口允许对象成为“for-each 循环”语句的目标。

List类的位置

在这里插入图片描述

jre\lib\rt.jar\java\util 下
也就是java本身自带的,不需要额外引用jar来实现

List的种类

  • ArrayList:底层由数组结构实现Object[],可以存储任何Object类型的对象,是非线程安全的
  • LinkedList:List和Deque接口的双向链表实现。实现所有可选列表操作,并允许所有元素(包括null )。所有操作都按照双向链表的预期执行。索引到列表中的操作将从开头或结尾遍历列表,以更接近指定索引的为准。
  • Vector:底层实现是动态数组的方式存放数据,是线程安全的,Vector源码当中每个方法都被synchronized关键字进行修饰,保证了Vector的线程安全,所以效率很低,尽量少使用

ArrayList

使用

        List list = new ArrayList<>();        
        List<Object> list1= new ArrayList<>();
        List<Map> list2= new ArrayList<>();
        List<Student> list3= new ArrayList<>();
        List<Object> list4 = new ArrayList<>(2);
        List<Object> list5 = new ArrayList<>(list);
        ...

实现方式

创建对象的时候会调用其无参构造方法

/**
 * Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;


/**
 * Shared empty array instance used for default sized empty instances. We
 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
 * first element is added.
 */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};




/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer. Any
 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
 * will be expanded to DEFAULT_CAPACITY when the first element is added.
 */
transient Object[] elementData; // non-private to simplify nested class access
    



/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}




/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
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);
    }
}



/**
 * Constructs a list containing the elements of the specified
 * collection, in the order they are returned by the collection's
 * iterator.
 *
 * @param c the collection whose elements are to be placed into this list
 * @throws NullPointerException if the specified collection is null
 */
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;
    }
}


可见,当创建ArrayList对象的时候就会创建好一个初始容量为 10 的空列表等待着被使用。

如何扩容



private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}


/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 */
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    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);
}


int newCapacity = oldCapacity + (oldCapacity >> 1);
每次自增一半,即原来的1.5倍

LinkedList

使用


        List list = new LinkedList<>();
        List<Object> list1 = new LinkedList<>();
        List<Map> list2 = new LinkedList<>();
        List<Student> list3 = new LinkedList<>();
        List<Object> list4 = new LinkedList<>(list);
        ...

实现方式

创建对象的时候会调用其无参构造方法



/**
 * Constructs an empty list.
 */
public LinkedList() {
}



/**
 * Constructs a list containing the elements of the specified
 * collection, in the order they are returned by the collection's
 * iterator.
 *
 * @param  c the collection whose elements are to be placed into this list
 * @throws NullPointerException if the specified collection is null
 */
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}


/**
 * Appends all of the elements in the specified collection to the end of
 * this list, in the order that they are returned by the specified
 * collection's iterator.  The behavior of this operation is undefined if
 * the specified collection is modified while the operation is in
 * progress.  (Note that this will occur if the specified collection is
 * this list, and it's nonempty.)
 *
 * @param c collection containing elements to be added to this list
 * @return {@code true} if this list changed as a result of the call
 * @throws NullPointerException if the specified collection is null
 */
public boolean addAll(Collection<? extends E> c) {
    return addAll(size, c);
}

LinkedList初始化为空

如何扩容

由于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;
    }
}

因此也没有扩容的机制,如有需求一直在其前面或者后面新增下去

Vector

使用

        Vector vector = new Vector<>();
        Vector<Object> vector1 = new Vector<>();
        Vector<Map> vector2 = new Vector<>();
        Vector<Student> vector3 = new Vector<>();
        ...

实现方式



/**
 * The array buffer into which the components of the vector are
 * stored. The capacity of the vector is the length of this array buffer,
 * and is at least large enough to contain all the vector's elements.
 *
 * <p>Any array elements following the last element in the Vector are null.
 *
 * @serial
 */
protected Object[] elementData;



/**
 * The amount by which the capacity of the vector is automatically
 * incremented when its size becomes greater than its capacity.  If
 * the capacity increment is less than or equal to zero, the capacity
 * of the vector is doubled each time it needs to grow.
 *
 * @serial
 */
protected int capacityIncrement;



/**
 * Constructs an empty vector so that its internal data array
 * has size {@code 10} and its standard capacity increment is
 * zero.
 */
public Vector() {
    this(10);
}



/**
 * Constructs an empty vector with the specified initial capacity and
 * with its capacity increment equal to zero.
 *
 * @param   initialCapacity   the initial capacity of the vector
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

/**
 * Constructs an empty vector with the specified initial capacity and
 * capacity increment.
 *
 * @param   initialCapacity     the initial capacity of the vector
 * @param   capacityIncrement   the amount by which the capacity is
 *                              increased when the vector overflows
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

可以看出Vector和ArrayList是非常相似的

  • 都是一个Object[]类型存储数据
  • 无参数构造默认数组容量是10
  • 使用有参数的构造方法可以指定容量的大小

如何扩容


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);
}

int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
每次自增一倍,即原来的2倍

常用方法

共有

  • int size();
    返回此列表中的元素数
  • boolean isEmpty();
    如果此列表不包含任何元素,则返回true
  • boolean contains(Object o);
    如果此列表包含指定元素,则返回true
  • Iterator iterator();
    以正确的顺序返回此列表中元素的迭代器
  • Object[] toArray();
    返回此列表中从第一个元素到最后一个元素的数组
  • boolean add(E e);
    将指定元素附加到此列表的末尾
  • boolean remove(Object o);
    如果指定元素存在,则从该列表中删除第一次出现的指定元素。如果此列表不包含该元素,则它不变
  • boolean addAll(Collection<? extends E> c);
    将指定集合中的所有元素附加到此列表的末尾,按照指定集合的​​迭代器返回的顺序
  • boolean removeAll(Collection<?> c);
    从此列表中删除包含在指定集合中的所有元素
  • void clear();
    从此列表中删除所有元素。此调用返回后,列表将为空
  • boolean equals(Object o);
    比较指定对象与此列表是否相等。当且仅当指定对象也是一个列表时返回true ,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等
  • E get(int index);
    返回此列表中指定位置的元素
  • E set(int index, E element);
    将此列表中指定位置的元素替换为指定元素
  • void add(int index, E element);
    在此列表中的指定位置插入指定元素。将当前位于该位置的元素和任何后续元素向右移动
  • E remove(int index);
    移除此列表中指定位置的元素
  • int indexOf(Object o);
    返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回 -1
  • int lastIndexOf(Object o);
    返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回 -1

LinkedList

  • E getFirst();
    返回此列表中的第一个元素
  • E getLast();
    返回此列表中的最后一个元素
  • E removeFirst();
    从此列表中删除并返回第一个元素
  • E removeLast();
    移除并返回此列表中的最后一个元素
  • void addFirst(E e);
    在此列表的开头插入指定元素
  • void addLast(E e);
    将指定元素附加到此列表的末尾
  • boolean hasNext();
    如果此列表迭代器在向前遍历列表时具有更多元素,则返回true
  • E next();
    返回列表中的下一个元素并前进光标位置

结尾

  • 上述内容绝大多数来自源码
  • 部分为自己总结

记:反复使用后的小总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值