ArrayList,Vector,LinkedList区别

    各位小伙伴,今天介绍哈ArrayList,Vector以及LinkedList的区别及其原理实现,JDK版本1.8;

介绍:

    1.ArrayList继承AbstractList,实现List,其List的子类

    2.Vector继承AbstractList,实现List,其List的子类

    3.LinkedList继承AbstractSequentialList,实现List,其List的子类,特别说明下也实现了其Deque,且Deque继承了Queue(队列)

说明:

    1.ArrayList底层实现原理是Object[],是以数组形式实现的;


  声明其数组类型的变量elementData,至于transient关键字(序列化与反序列化,针对属性值的安全),大家有兴趣的朋友可以深入了解下.


  在添加的方法中,很明显的看其在添加的时候就是在添加当elementData数组中.在添加中最重要的使用原理:

  

  

  ArrayList在add方法中返回的数组是 从一个旧的数组copy到一个新的数组是根据适应性扩容数得到一个新的数组,所以在这方面是非常的耗时;


  在我们常用的get方法中,就是根据索引index进行获取数组elementData当中的值.

    2.Vector底层原理实现跟ArrayList实现是一样的Object[],都是数组:

    

    声明其数组elementData属性;

   

   在添加的方法中,很明显的看其在添加的时候就是在添加当elementData数组中,那么比ArrayList多的就是在方法上我们看见了我们熟悉的synchronized关键字(同步锁),看到这个关键字大家心里就明白了为什么Vector线程安全了吧!

   备注:同步锁的使用,简单的介绍哈,如上面在add方法上加synchronized,那么在2个线程同时执行add方法时,第一个线程先执行完add方法的话,第二个线程是阻塞的,必须要等待第一个线程执行完才能轮到第二个线程执行add方法.

   其它同ArrayList同理,在差距上就在方法上了多一个synchroized关键字.  

   3.Linkedlist底层实现原理是链表(双向链表) Node<E>(双向节点),

  

   查看LinkedList有三个成员变量:

   transient int size  集合数量;   transient Node<E> first 第一个节点对象;  transient Node<E> last 最后一个节点对象; 其中是根据transient进行声明的,在前面ArrayList当中也用到过,transient(序列号与反序列化,针对属性值安全)

   Node对象: E item 在add方法时候,存放的对象;   Node<E> prev 上一个节点对象;  Node<E> next 下一个节点对象

   通过介绍了LinkedList双向链表实现的几个比较重要的变量,那么我们进入到LinkedList,解谜LinkedList的链表实现,首先看其比较常用的的方法:

  

   在添加的方法中,我们看到有了add方法执行了LinkLast方法,在有图中,我们看到了其LinkLast方法,我们来解析下linkLast方法:

   LinkedList<Integer> list=new LinkedList<Integer>();

   list.add(10000);   进入到linkLast(E e)方法,示例进入方法,进入方法说明

   final Node<E> l = null; //第一次last变量为null;

   final Node<E> newNode = new Node<>(l,10000,null); //进入到Node对象赋值,prev为null;element为10000;next为null

   last = newNode;//赋值last为最后一个对象为newNode,目前只添加了一个,那么最后一个节点对象肯定就是为10000的节点对象
   if(l == null){//第一次执行add方法时,l为null,就赋值first为10000的对象
     first = newNode;
   }else{//当第二次或者第三次或者更多执行add方法时,l.next即为赋值下一个对象next;
     l.next = newNode;
   }
   size++;//linkedlist的数量为1

   modeCount++;

   list.add(20000);   第二次进入到linkLast(E e)方法,示例进入方法,进入方法说明

   final Node<E> l = last; //第二次last变量为10000的Node对象;

   final Node<E> newNode = new Node<>(l,20000,null); //进入到Node对象赋值,prev为10000的Node对象;element为20000;next为null

   last = newNode; //赋值last为最后一个对象为newNode,又添加了一个,那么最后一个节点对象肯定就是为20000的节点对象
   if(l == null){ //第一次执行add方法时,l为null,就赋值first为10000的对象
     first = newNode;
   }else{ //当第二次或者第三次或者更多执行add方法时,last为10000的节点对象,l.next即为赋值下一个对象next;那么这个20000的newNode对象进入到该方法,
     l.next = newNode;l.next就为20000的对象,就会赋值10000的Node对象的next为20000的对象
   }
   size++;//linkedlist的数量为2

   modeCount++;

  

   list.add(30000);   第二次进入到linkLast(E e)方法,示例进入方法,进入方法说明

  final Node<E> l = last; //第二次last变量为20000的Node对象;

   final Node<E> newNode = new Node<>(l,30000,null); //进入到Node对象赋值,prev为20000的Node对象;element为30000;next为null

   last = newNode; //赋值last为最后一个对象为newNode,又添加了一个,那么最后一个节点对象肯定就是为30000的节点对象
   if(l == null){ //第一次执行add方法时,l为null,就赋值first为10000的对象
     first = newNode;
   }else{ //当第二次或者第三次或者更多执行add方法时,last为20000的节点对象,l.next即为赋值下一个对象next;那么这个30000的newNode对象进入到该方法,
     l.next = newNode;l.next就为30000的对象,就会赋值20000的Node对象的next为30000的对象
   }
   size++;//linkedlist的数量为3

   modeCount++;

   根据代码实例分析,很明显的看到Linkedlist集合对象的底层实现就是个双向链表,只要知道first Node对象以及last Node对象,我们就能查找到所有对象;

   first Node<E> prev为null;elment为10000;next为20000的Node对象;

   last Node<E> prev为20000的对象;element为30000;next为null;

   通过以上得知,我们在LinkedList添加的时候,效率是非常高的,直接通过赋值next或者prev就能直接添加指定职位;

   下面我通过一个草图来表达下这个LinkedList对象:

   

   根据上面的草图,大家一看就明了,看着就像一个树形结构一样,next指定下一个节点对象,prev指定上一个节点对象,一层一层互相关联;所以通过上面的结构我们很明显的知道了Linkedlist查找起来就非常的痛苦,需要一层层的查找;所以效率方面就非常的低;在LinkedList里面如果要查找指定的某个节点,LinkedList做了一些小小的优化,就是单单的减少了查找的次数而已,但是效率还是非常的低,在linkedlist.size()比较大的情况下,查看源码:

      

  在上面我们看到了,通过index,先进行判断index是否小于数量/2,如果小于,就从头部开始查找,如果大于数量/2,那么就从尾部开始查找,这就是为什么LinkedList查找我们需要的节点时慢了.而ArrayList,Vector查找就比较快,通过index直接获取数组指定的值;

  我们基本简单源码分析完了ArrayList,Vector,LinkedList;进行相应的总结:

 1.ArrayList        数组   查找效率高   添加效率低    线程不安全        有序

 2.Vertor            数组   查找效率高   添加效率低    线程安全           有序

 3.LinkedList      链表   查找效率低   添加效率高    线程不安全        有序

还有一种保证线程安全的写法:

  Collections.synchroizedList(new ArrayList());

  Collections.synchroizedList(new LinkedList());


总体完毕,谢谢大家!







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值