`
liwenshui322
  • 浏览: 511259 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java ArrayList与LinkedList知识点

阅读更多

一 ArrayList

         1.  arraylist里面是通过数组实现的

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. /** 
  2.     * The array buffer into which the elements of the ArrayList are stored. 
  3.     * The capacity of the ArrayList is the length of this array buffer. 
  4.     */  
  5.    private transient Object[] elementData;  
  6.   
  7.    /** 
  8.     * The size of the ArrayList (the number of elements it contains). 
  9.     * 
  10.     * @serial 
  11.     */  
  12.    private int size;  


         2. arraylist初始化的时候可以指定大小,如果你知道大小,在创建的时候最好指定

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public ArrayList(int initialCapacity) {  
  2.     super();  
  3.         if (initialCapacity < 0)  
  4.             throw new IllegalArgumentException("Illegal Capacity: "+  
  5.                                                initialCapacity);  
  6.     this.elementData = new Object[initialCapacity];  
  7.     }  


         3. arraylist添加元素的时候,需要判断存放元素的数组是否需要扩容(扩容大小是原来大小的1/2+1)

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public boolean add(E e) {  
  2.     ensureCapacity(size + 1);  // Increments modCount!!  
  3.     elementData[size++] = e;  
  4.     return true;  
  5.     }  
  6.   
  7.  public void ensureCapacity(int minCapacity) {  
  8.     modCount++;  
  9.     int oldCapacity = elementData.length;  
  10.     if (minCapacity > oldCapacity) {  
  11.         Object oldData[] = elementData;  
  12.         int newCapacity = (oldCapacity * 3)/2 + 1;  
  13.             if (newCapacity < minCapacity)  
  14.         newCapacity = minCapacity;  
  15.             // minCapacity is usually close to size, so this is a win:  
  16.             elementData = Arrays.copyOf(elementData, newCapacity);  
  17.     }  
  18.     }  


        4. arraylist 在指定位置添加元素或者移除指定位置元素,需要移动比较多的数据

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public void add(int index, E element) {  
  2.     if (index > size || index < 0)  
  3.         throw new IndexOutOfBoundsException(  
  4.         "Index: "+index+", Size: "+size);  
  5.   
  6.     ensureCapacity(size+1);  // Increments modCount!!  
  7.     System.arraycopy(elementData, index, elementData, index + 1,  
  8.              size - index);  
  9.     elementData[index] = element;  
  10.     size++;  
  11.     }  
  12.   
  13.     public E remove(int index) {  
  14.     RangeCheck(index);  
  15.   
  16.     modCount++;  
  17.     E oldValue = (E) elementData[index];  
  18.   
  19.     int numMoved = size - index - 1;  
  20.     if (numMoved > 0)  
  21.         System.arraycopy(elementData, index+1, elementData, index,  
  22.                  numMoved);  
  23.     elementData[--size] = null// Let gc do its work  
  24.   
  25.     return oldValue;  
  26.     }  


二.  LinkedList

 

          1. linkedlist是通过链表实现的,一个节点是一个对象,包含了自己前一个节点的和后一个节点的地址

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. private transient Entry<E> header = new Entry<E>(nullnullnull);  
  2.     private transient int size = 0;  
  3.   
  4.  private static class Entry<E> {  
  5.     E element;  
  6.     Entry<E> next;  
  7.     Entry<E> previous;  
  8.   
  9.     Entry(E element, Entry<E> next, Entry<E> previous) {  
  10.         this.element = element;  
  11.         this.next = next;  
  12.         this.previous = previous;  
  13.     }  
  14.     }  

         2. 添加元素是通过移动链表指针

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public boolean add(E e) {  
  2.     addBefore(e, header);  
  3.         return true;  
  4.     }  
  5. private Entry<E> addBefore(E e, Entry<E> entry) {  
  6.     Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);  
  7.     newEntry.previous.next = newEntry;  
  8.     newEntry.next.previous = newEntry;  
  9.     size++;  
  10.     modCount++;  
  11.     return newEntry;  
  12.     }  

         3. 删除元素也是通过移动指针,所以理论上linkedlist比arraylist更适合添加和删除操作(不需要判断是否需要扩容,不需要移动大批的元素)

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1.  public boolean remove(Object o) {  
  2.         if (o==null) {  
  3.             for (Entry<E> e = header.next; e != header; e = e.next) {  
  4.                 if (e.element==null) {  
  5.                     remove(e);  
  6.                     return true;  
  7.                 }  
  8.             }  
  9.         } else {  
  10.             for (Entry<E> e = header.next; e != header; e = e.next) {  
  11.                 if (o.equals(e.element)) {  
  12.                     remove(e);  
  13.                     return true;  
  14.                 }  
  15.             }  
  16.         }  
  17.         return false;  
  18.     }  
  19.   
  20. private E remove(Entry<E> e) {  
  21.     if (e == header)  
  22.         throw new NoSuchElementException();  
  23.   
  24.         E result = e.element;  
  25.     e.previous.next = e.next;  
  26.     e.next.previous = e.previous;  
  27.         e.next = e.previous = null;  
  28.         e.element = null;  
  29.     size--;  
  30.     modCount++;  
  31.         return result;  
  32.     }  

         4. 获取元素需要遍历链表,比arraylist要慢

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public E get(int index) {  
  2.         return entry(index).element;  
  3.     }  
  4. private Entry<E> entry(int index) {  
  5.         if (index < 0 || index >= size)  
  6.             throw new IndexOutOfBoundsException("Index: "+index+  
  7.                                                 ", Size: "+size);  
  8.         Entry<E> e = header;  
  9.         if (index < (size >> 1)) {//size 右移一位表示除以2,其实就是看从前遍历快还是从后遍历快  
  10.             for (int i = 0; i <= index; i++)  
  11.                 e = e.next;  
  12.         } else {  
  13.             for (int i = size; i > index; i--)  
  14.                 e = e.previous;  
  15.         }  
  16.         return e;  
  17.     }  

          5. linkedlist 迭代器,支持向前向后迭代,在迭代过程中移除元素。如果要遍历linkedlist,建议使用迭代器,因为如果使用get方法效率没迭代器高。(从get方法的源码可以看出)

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. private class ListItr implements ListIterator<E> {  
  2. private Entry<E> lastReturned = header;  
  3. private Entry<E> next;  
  4. private int nextIndex;  
  5. private int expectedModCount = modCount;  
  6.   
  7. ListItr(int index) { //支持从指定位置开始迭代  
  8.     if (index < 0 || index > size)  
  9.     throw new IndexOutOfBoundsException("Index: "+index+  
  10.                         ", Size: "+size);  
  11.     if (index < (size >> 1)) {  
  12.     next = header.next;  
  13.     for (nextIndex=0; nextIndex<index; nextIndex++)  
  14.         next = next.next;  
  15.     } else {  
  16.     next = header;  
  17.     for (nextIndex=size; nextIndex>index; nextIndex--)  
  18.         next = next.previous;  
  19.     }  
  20. }  
  21.   
  22. public boolean hasNext() {//是否有下一个  
  23.     return nextIndex != size;  
  24. }  
  25.   
  26. public E next() { //下一个  
  27.     checkForComodification();  
  28.     if (nextIndex == size)  
  29.     throw new NoSuchElementException();  
  30.   
  31.     lastReturned = next;  
  32.     next = next.next;  
  33.     nextIndex++;  
  34.     return lastReturned.element;  
  35. }  
  36.   
  37. public boolean hasPrevious() { //是否有前一个  
  38.     return nextIndex != 0;  
  39. }  
  40.   
  41. public E previous() { //前一个  
  42.     if (nextIndex == 0)  
  43.     throw new NoSuchElementException();  
  44.   
  45.     lastReturned = next = next.previous;  
  46.     nextIndex--;  
  47.     checkForComodification();  
  48.     return lastReturned.element;  
  49. }  
  50.   
  51. public int nextIndex() {  
  52.     return nextIndex;  
  53. }  
  54.   
  55. public int previousIndex() {  
  56.     return nextIndex-1;  
  57. }  
  58.   
  59. public void remove() { //删除元素  
  60.            checkForComodification();  
  61.            Entry<E> lastNext = lastReturned.next;  
  62.            try {  
  63.                LinkedList.this.remove(lastReturned);  
  64.            } catch (NoSuchElementException e) {  
  65.                throw new IllegalStateException();  
  66.            }  
  67.     if (next==lastReturned)  
  68.                next = lastNext;  
  69.            else  
  70.     nextIndex--;  
  71.     lastReturned = header;  
  72.     expectedModCount++;  
  73. }  
  74.   
  75. public void set(E e) {  
  76.     if (lastReturned == header)  
  77.     throw new IllegalStateException();  
  78.     checkForComodification();  
  79.     lastReturned.element = e;  
  80. }  
  81.   
  82. public void add(E e) {  
  83.     checkForComodification();  
  84.     lastReturned = header;  
  85.     addBefore(e, next);  
  86.     nextIndex++;  
  87.     expectedModCount++;  
  88. }  
  89.   
  90. final void checkForComodification() {  
  91.     if (modCount != expectedModCount)  
  92.     throw new ConcurrentModificationException();  
  93. }  
  94.    }  
0
5
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics