ArrayList浅析

什么是链表?

链表,顾名思义,是一条相互链接的数据节点表。每个节点由两部分组成:数据和指向下一个节点的指针。链表的基本结构如下图所示: 
链表结构图 
一般来说,链表的头结点不存放具体的数据,所以也被称为哑节点(dummy node)。原因在于这样可以比较好地区分链表的头结点,而且可以大大简化链表的各种操作,避免很多不必要的边界讨论。

链表的种类

单向链表 双向链表 循环链表 多向表(网状表)

链表的优缺点

这里的优缺点主要是和链表对应的另一个数据结构:数组相比得出的。 
链表的优点在于: 
1.物理存储单元上非连续,而且采用动态内存分配,能够有效的分配和利用内存资源; 
2.节点删除和插入简单,不需要内存空间的重组。 
作为一种数据结构,链表必然也有让人诟病的地方。链表的缺点在于: 
1.不能进行索引访问,只能从头结点开始顺序查找; 
2.数据结构较为复杂,需要大量的指针操作,容易出错。

数组

所谓数组,就是相同数据类型的元素按一定顺序排列的集合


=====================================================================================
构造方法摘要
ArrayList()
          构造一个初始容量为 10 的空列表。
ArrayList(Collection<? extends E> c)
          构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity)
          构造一个具有指定初始容量的空列表。

List数组:

ArrayList,Vector, LinkedList的存储性能和特性

ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

ArrayList底层是数组
List是线性表的数据结构,ArrayList是顺序存储的线性表,ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输

LinkedList底层是链表
LinkedList是链式存储的线性表,实质是双向链表,实现了List和Deque接口。Deque代表双端队列,既可以当做队列也可以当作栈。

Vector和ArrayList区别
Vector提供synchronized修饰方法,是线程安全版本的ArrayList
.Vector 本质是一个数组,其实所有集合都是数组,从JAVA 来说搞成了对象

ArryList和Vector可变长度数组的原理:
    当默认10的长度的数组不够存储时,会建立一个新数组。将原来数组的内容拷贝到新的数组当中,并将新增加的元素追加到拷贝完的数组尾,如果仍然不够重复上述动作。其中,ArryList的增加是以原来50%长度进行增加,而Vector是按照100%延长。这里在添一点就是:ArryList是线程不安全的,Vector是安全的。由于是否有锁的判断将影响效率。故Arrylist效率远远高于Vector。而且只要是常用的容器就不是同步的,因为同步效率比较低。


ArrayList()初始化时为10的空列表

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

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this(10);
    }
add时计算当前最小的长度和最大(10)的比较:

知识点:>>1是二分之一的表示形式

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // size初始化为0                         
        elementData[size++] = e;
        return true;
    }                


private void ensureCapacityInternal(int minCapacity) {
        modCount++;//protected transient int modCount = 0;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)// private transient Object[] elementData;初始化数组
            grow(minCapacity);
    }

 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);// 复制指定的数组,截取或用 null 填充(如有必要),以使副本具有指定的长度
    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值