错题笔记(七)

Arraylist的内存结构是数组,当超出数组大小时创建一个新的数组,吧原数组中元素拷贝过去。其本质是顺序存储的线性表,插入和删除操作会引发后续元素移动,效率低,但是随机访问效率高

LinkedList的内存结构是用双向链表存储的,链式存储结构插入和删除效率高,不需要移动。但是随机访问效率低,需要从头开始向后依次访问

//ArrayList源码
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
 
//LinkedList源码
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

ArrayList的大小是可以改变的,通过源码可以发现,它是基于数组实现的,往ArrayList里添加数据时,它首先会判断数组大小,是否已满(这个与HashMap不同,那个有装载因子),如果满了,则扩充数组,其实就是新建一个数组,然后把数据拷贝过去,新数组的大小与旧数组的大小关系如下。相信大伙都看得懂。

int newCapacity = oldCapacity + (oldCapacity >> 1);

LinkedList是节点结构如下,可以看出,item是存储数据的,next是指向下一个Node,prev是指向前一个Node的,所以说,LinkedList是双向的

Node(Node<E> prev, E element, Node<E> next) {
    this.item = element;
    this.next = next;
    this.prev = prev;
}

ArrayList是基于数组的,所以,具备随机访问特点,但LinkedList就不一样了,虽然,也可以通过也支持随机访问,但却付出了一定的代价。在LInkedLIst中,如果想返回某个位置的元素,就是从前往后遍历。如下。很明显,LinkedLIst不支持高效的随机访问。

Node<E> node(int index) {
    // assert isElementIndex(index);
 
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

LinkedList是基于双链表的,增加是在尾部增加,增加和删除都只需要修改指针,不需要移动元素。

ArrayList插入或删除一个元素的开销不是固定的。在插入时,如果索引正确,容量够,则直接插入,插入位置之后的都需要移动,如果容易不够,还得扩充容量,开销当然不一样。删除操作同理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值