Arraylist 与 LinkedList解析和区别
发布日期:2022-02-10 13:35:58 浏览次数:24 分类:技术文章

本文共 2687 字,大约阅读时间需要 8 分钟。

一、 Arraylist

  1. 如下图可知:ArrayList是List接口的实现类,因此实现了List的所有未实现的方法,而List接口继承了Collection接口,Collection接口又继承了Iterable接口,因此可以看出List同时拥有了Collection与Iterable接口的特性.
    这里写图片描述
  2. Arraylist的底层是通过动态数组来实现,所以他的查找和设值通过数组的索引能很快定位。
/**     * 默认初始容量 10     */    private static final int DEFAULT_CAPACITY = 10;

看它的源码可知默认的初始容量是10,但是这个初始容量并不是他的初始长度,如果你新建一个arraylist,打印它的size你会发现结果是0.这个初始容量是指目前可以存放的值最多为10个,

public class Arraylistdemo {    public static void main(String[] args) {        List  list = new ArrayList(20);        System.out.println(list.size());                // 输出为0        list.add(3);        list.add(5);        System.out.println(list.size());                // 输出为2    }}

3.此时如果已经有十个值,还要往里面添加怎么办,他的源码中有个方法grow,会实现自动扩容。

private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        //>>位运算,右移动一位。 整体相当于newCapacity =oldCapacity + 0.5 * oldCapacity         // 大约扩容为之前的1.5倍        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);    }

4.如果要在指定位置出增加值,此时容量已满怎么办:

public void add(int index, E element) {       rangeCheckForAdd(index);       ensureCapacityInternal(size + 1);  // Increments modCount!!       System.arraycopy(elementData, index, elementData, index + 1,                         size - index);       elementData[index] = element;       size++;    }

原理如下:

首先生成了一个扩容后的数组,然后把之前的数组赋值进去,此时位置还没变只是数组的长度变了,然后又用了system.copy方法,把需要挪动的数组往后移了一下位置。然后把最新需要插入的元素赋值到那个位置。

*System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。其函数原型是:public static void (Object src, int srcPos,Object dest,int destPos, int length);src:源数组;    srcPos:源数组要复制的起始位置;dest:目的数组;    destPos:目的数组放置的起始位置;    length:复制的长度。注意:src and dest都必须是同类型或者可以进行转换类型的数组.这个函数可以实现自己到自己复制,比如:int[] fun ={
0,1,2,3,4,5,6};System.arraycopy(fun,0,fun,3,3);则结果为:{
0,1,2,0,1,2,6};实现过程是这样的,先生成一个长度为length的临时数组,将fun数组中srcPos到srcPos+length-1之间的数据拷贝到临时数组中,再执行System.arraycopy(临时数组,0,fun,3,3)*

总结:在指定位置除增加值的过程复制了两次:一次是就数组复制到最新的扩容后的数组中,一次是最新的数组自我复制从指定索引出复制到索引加一处,最后在索引出赋值。

二、LinkedList

  1. 如下图可知:LinkedList是List接口的实现类,因此实现了List的所有未实现的方法,而List接口继承了Collection接口,Collection接口又继承了Iterable接口,因此可以看出List同时拥有了Collection与Iterable接口的特性.也实现了cloneable接口支持克隆,实现了Serializable接口,因此它支持序列化,能够通过序列化传输.实现了Deque接口,一个线性 collection,支持在两端插入和移除元素,定义了双端队列的操作。
    这里写图片描述
  2. LinkedList的底层是通过双向链表实现,所以不存在空间不足的问题,并且他的增加和删除效率很高,效率是相对而言,看具体的数据量。

总结:

一、ArrayList是实现了基于动态数组的数据结构,而LinkedList是基于双向链表的数据结构。
二、对于取值和设值,ArrayList要优于LinkedList,因为LinkedList要移动指针;

转载地址:https://blog.csdn.net/zoran_/article/details/80035409 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java集合
下一篇:Benewake TFmini-S\TFmimi Plus\TFluna\TF02-Pro\TF03雷达在PYTHON上的例程

发表评论

最新留言

很好
[***.229.124.182]2024年04月15日 20时22分07秒