高级java工程师-----vector和ArrayList和linklist的内部数据结构

Java面试中关于容器类List,Set是必问题目。但在我的面试经历中很难遇到满意的答复。大部分只能了解其大概使用方法,对其内部结构缺乏了解,错误的使用方式会导致性能大幅下降。
   首先介绍ArrayList,顾名思义内部数据结构是数组
Java代码   收藏代码
  1. private transient Object[] elementData;  
  2. private int size;  
  3. public ArrayList(int initialCapacity){  
  4. }  

   在增加元素时,若容量不足进行扩充
Java代码   收藏代码
  1.    public void ensureCapacity(int minCapacity) {  
  2. modCount++;  
  3. int oldCapacity = elementData.length;  
  4. if (minCapacity > oldCapacity) {  
  5.     Object oldData[] = elementData;  
  6.     int newCapacity = (oldCapacity * 3)/2 + 1;  
  7.         if (newCapacity < minCapacity)  
  8.     newCapacity = minCapacity;  
  9.            // minCapacity is usually close to size, so this is a win:  
  10.            elementData = Arrays.copyOf(elementData, newCapacity);  
  11. }  
  12.    }  

   新数组大小为之前数组大小*1.5+1 ,加上1保证oldCapacity为1的情况也能扩充为2
  (类似分页时总页数=(总记录数+ (每页记录数-1))/每页记录数算法)

   删除元素时通过 System.arraycopy把删除位置后的所有元素前移一个位置实现

Vector中:


  1. private void ensureCapacityHelper(int minCapacity) {  
  2.    
  3.      int oldCapacity = elementData.length;  
  4.    
  5.      if (minCapacity > oldCapacity) {  
  6.    
  7.          Object[] oldData = elementData;  
  8.    
  9.          int newCapacity = (capacityIncrement > 0) ?  
  10.    
  11.         (oldCapacity + capacityIncrement) : (oldCapacity * 2);  
  12.    
  13.          if (newCapacity < minCapacity) {  
  14.    
  15.         newCapacity = minCapacity;  
  16.    
  17.          }  
  18.    
  19.           elementData = Arrays.copyOf(elementData, newCapacity);  
  20.    
  21.      }  
  22.    
  23.  } 
vector当增加数组大小时是默认扩展一倍






Java代码   收藏代码
  1. public E remove(int index) {  
  2.     RangeCheck(index);  
  3.   
  4.     modCount++;  
  5.     E oldValue = (E) elementData[index];  
  6.   
  7.     int numMoved = size - index - 1;  
  8.     if (numMoved > 0)  
  9.         System.arraycopy(elementData, index+1, elementData, index,  
  10.                  numMoved);  
  11.     elementData[--size] = null// Let gc do its work  
  12.   
  13.     return oldValue;  
  14.     }  

 
 
  LinkedList大家都知道是通过链表实现,内部是一个双向链表
Java代码   收藏代码
  1. public class LinkedList<E>  
  2.     extends AbstractSequentialList<E>  
  3.     implements List<E>, Deque<E>, Cloneable, java.io.Serializable  
  4. {  
  5.     private transient Entry<E> header = new Entry<E>(nullnullnull);  
  6.     private transient int size = 0;  
  7. }  
  8. private static class Entry<E> {  
  9.     E element;  
  10.     Entry<E> next;  
  11.     Entry<E> previous;  
  12. }  

插入和删除都只要改动前后节点的next和previous实现

总结特点如下:
类型内部结构顺序遍历速度随机遍历速度追加代价插入代价删除代价占用内存
ArrayList数组
LinkedList双向链表

所以:
  • 一般顺序遍历情况下使用ArrayList,但注意构造函数中设置初始大小
  • 尽量不对ArrayList进行插入或删除操作(删除尾部除外),若有多次删除/插入操作又有随机遍历的需求,可以再构建一个ArrayList,把复合条件的对象放入新ArrayList,而不要频繁操作原ArrayList
  • 经常有删除/插入操作而顺序遍历列表的情况下最适合使用Linkedlist

综上所述:那么 Collection的List下的Vector和ArrayList和LinkedList有什么异同???

首先vector和ArrayList都是基于Aarry的线性数组,vector是线程安全的而ArrayList不是,ArrayList动态增加数组大小的模式是当新增的大小超出了原有数组的范围,ArrayList就会在原来基础上增加到原来数组大小的1.5倍+1,加1是为了当数组大小为1时也能根据该流程将数组大小扩充到2.

ArrayList和LinkedList的区别,ArrayList是线性数组而LinkedList是双向链表数组内部结构是节点元素和向前节点和向后节点,所以ArrayList查询的速度相对较快,LinkedList的插入删除更新相对较慢。另Linkedlist还提供了list没有提供的方法,linkedlist专门用于操作表头和表尾,可以当做堆、队列和双向队列操作。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值