Java集合1——Java容器之List

1. 容器整体框架图

在这里插入图片描述

1.1 List集合

List集合的特点:有序,可重复

  • 有序:List中的每个元素都有索引标记,可以根据元素的索引标记访问元素
  • 可重复:List中允许放入重复的元素

List接口常用的三个实现类:ArrayList, LinkedList , Vector

  1. ArrayList:底层用数组实现。特点:查询效率高,增删效率低,线程不安全。可以动态增长和缩减的一个索引序列。
  2. LinkedList:底层用双向链表实现。特点:查询效率低,增删效率高,线程不安全。可以在任何位置高效插入和删除的一个有序序列。
  3. Vector:底层用数组实现。特点:线程安全,效率低。

1.1.1 ArrayList

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. 实现了RandomAccess接口,支持快速随机访问。因为ArrayList底层用数组实现,所以可以快速随机访问其中的元素。实现了RandomAccess接口的类用for循环的方式获取数据要优于用迭代器获取数据。
As a rule of thumb,this loop:
 * <pre>
 *     for (int i=0, n=list.size(); i &lt; n; i++)
 *         list.get(i);
 * </pre>

runs faster than this loop

 <pre>
 *     for (Iterator i=list.iterator(); i.hasNext(); )
 *         i.next();
 * </pre>
  • 实现了Cloneable接口。在类中重写Object中的clone()方法,创建并返回此实例的副本。如果没有实现该接口,则会抛出 CloneNotSupportedException 异常。
    重写clone()方法的原则:
    (1) x.clone != x (true)
    (2)x.clone().getClass()==x.getClass() (true)
    (3)x.clone().equals(x) (true)
protected native Object clone() throws CloneNotSupportedException;
  • 实现了 Serializable 接口。(官方文档的解释)
    没有实现此接口的类不会对其状态进行任何序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
Classes that do not implement this interface will not have any of their state serialized or deserialized.  
All subtypes of a serializable class are themselves serializable.  The serialization 
interface has no methods or fields and serves only to identify the semantics of being serializable.

(1)什么情况需要序列化(看了GNG博主给出的解释,写的很通俗易懂,很容易理解。)
序列化的定义:把原本在内存中的对象状态变成可存储或传输的过程称之为序列化

 * 当你想把的内存中的对象状态保存到一个文件中或者数据库中,以便可以在以后重新创建精确的副本;
 * 当你想用套接字在网络上传送对象的时候(从一个应用程序域发送到另一个应用程序域中);
 * 当你想通过RMI传输对象的时候;
1.1.1.1 ArrayList的属性
    // 默认的初始容量
    private static final int DEFAULT_CAPACITY = 10;

    // 空的数组
    private static final Object[] EMPTY_ELEMENTDATA = {};

	// 默认容量的空数组。(官方文档有这么一句话)
	// We distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when first 
	// element is added.(与EMPTY_ELEMENTDATA的区别:当第一个元素被加入进来的时候它知道如何扩张)
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    // 存储ArrayList的元素的数组缓冲区。添加第一个元素时,任何具有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空ArrayList都将扩展为DEFAULT_CAPACITY。
    transient Object[] elementData; // non-private to simplify nested class access

    // ArrayList的大小(它包含的元素数)
    private int size;
1.1.1.2 ArrayList的构造函数
  • 无参构造函数
// 直接将DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData
public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
  • 带 int 的构造函数
// 首先判断initialCapacity是否为0,如果是0,则将EMPTY_ELEMENTDATA赋值给elementData,如果大于0,就将elementData初始化为一个容量为initialCapacity的对象数组。如果小于0,抛出异常。
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);
        }
    }
  • 带 Collection 形参的构造函数
    首先调用Collection的 toArray()方法,将结果赋值给elementData。如果elementData的长度为0,则将EMPTY_ELEMENTDATA赋值给elementData。如果不为0,则进行判断,c.toArray()不返回Object[],所以有 if (elementData.getClass() != Object[].class)的判断,如果if成立,进行数组拷贝。
public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // defend against c.toArray (incorrectly) not returning Object[]
            // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

1.1.2 LinkedList

  • LinkedList是一个继承于 AbstractSequentialList 的双向链表,可以被当作堆栈、队列或双端队列进行操作。
  • LinkedList实现Deque接口,能够将LInkedList当做双端队列使用。(双端队列允许在头部和尾部都高效的添加或删除元素,不支持在队列中间添加元素。)
  • LinkedList实现List接口,能对它进行队列操作。
  • LinkedList实现了Cloneable接口。(和ArrayList一样)
  • LinkedList实现了Serializable接口。(和ArrayList一样)
1.1.2.1 LinkedList的属性
	// 链表节点个数
	transient int size = 0;
    // 首节点
    transient Node<E> first;
    // 尾结点
    transient Node<E> last;
1.1.2.2 LinkedList的构造函数
  • 无参构造函数
// Constructs an empty list.(创建一个空的列表)
public LinkedList() {
    }
  • 带Collection的构造函数
//Constructs a list containing the elements of the specified collection, in the order they
//are returned by the collection's iterator.(构造一个包含指定集合元素的列表,其顺序由集合的迭代器返回)
public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值