ArrayList 和 LinkedList 的一些小结

来源:互联网 发布:西安聚云网络诈骗 编辑:程序博客网 时间:2024/06/05 15:35


            网上关于ArrayList和LinkedList比较的文章实在是多如牛毛 我看了一些 基本上大同小异 当然也有很多深入讲解的文章 这里些众所周知的东西就不说了 比如ArrayList是Object数组实现的 LinkedList是双向链表 ArrayList适合随机访问 LinkedList随机增加删除效率高 所以想再深入研究的话 就必须要结合JDK的源代码了
       这一段儿看了这两个类和与他们有关类的源代码之后 做个小小的总结
       
       1. ArrayList的size属性 并非真正Object数组的长度
      
通常来说size总是更小一些 调用ArrayList的无参构造方法的话 Object数组的初始长度会默认是10 至于为什么是10 我不大清楚 size是只有在我们用add或者remove这一类方法的时候 才会做出改变 比如通过这样来创建一个ArrayList
       

    List list = new ArrayList();    list.add("one");

      并通过add向里面添加一个元素 这时候 list的size是1 而Object的长度是10 如果这时候调用add(2,"two"); 就会报错(对 就是那个臭名昭著的 IndexOutOfBoundsException) 因为2超过了这个size 但是调用add(1,"two");就不会报错 而且size会增加1
      当然 我们可以通过ensureCapacity方法和trimToSize方法来调整Object数组的大小 不过似乎没有一个完美的精确指定数组大小的方法

      2.Object数组的容量如何自动增加
      我曾经想当然地认为 当容量不足时 每次自动加10 这似乎是很容易想到的 来看看源代码是如何实现的


      
public void ensureCapacity(int minCapacity) {modCount++;int oldCapacity = elementData.length;if (minCapacity > oldCapacity) {    Object oldData[] = elementData;    int newCapacity = (oldCapacity * 3)/2 + 1; //是以原数组长度的1.5倍+1来递增的        if (newCapacity < minCapacity)newCapacity = minCapacity;            // minCapacity is usually close to size, so this is a win:            elementData = Arrays.copyOf(elementData, newCapacity);}    }

     可能有些童鞋以为ensureCapacity方法可以指定Object数组(就是上面的elementData)的大小 可这并不总是对的 数组的长度会取 minCapacity 和 原长度的1.5倍加1 两种中较大的那个 加1是考虑到0和1的情况 至于为什么是1.5倍而不是我原先以为的10 可能是害怕频繁地增加长度而频繁地进行数组COPY效率比较低吧 
      
     3.LinkedList的增加和删除真的效率高么
    
是一个封装的双向链表 形成一个环 链表的节点用内部类Entry来进行实现 有一个头节点 header 但他并不计入size 对于随机增加元素 效率确实比ArrayList高 因为少了元素移动的过程  但是对于删除 效率并没有想象的好 remove(Object o)方法的复杂度是O(n) 因为有一个遍历查找的过程 remove(int index)的复杂度也是O(n) 不过有一个优化的过程 就是看指定的元素是在链表的前半段还是后半段 就会分别从前或者从后查找(因为是一个环)
     确实没有想象的好(不是O(1)) 但还是比ArrayList高效 因为少了数组元素移动的过程



原创粉丝点击