• 内功心法 -- java.util.ArrayList<E> (5)


    写在前面的话:读书破万卷,编码如有神
    --------------------------------------------------------------------
    下文主要对java.util.ArrayList<E>中的Iterator和List操作进行介绍,主要内容包括:

    1、ArrayList的Iterator和ListIterator操作

    2、ArrayList的subList操作

    参考内容:

    1、JDK源码(1.7)

    -------------------------------------------------------------------- 

    1. ArrayList的Iterator和List操作                                                                         

    Iterator和子List操作 

    关于Iterator操作这里涉及到"迭代器模式",可以简单看看

    (1)Iterator<E> iterator()       

    功能: 返回列表的Iterator实例

    示例代码:

     1 import java.util.ArrayList;
     2 import java.util.Iterator;
     3 
     4 public class ArrayListTest {
     5     public static void main(String[] args) {
     6         ArrayList<Integer> list = new ArrayList<Integer>();
     7         list.add(22);
     8         list.add(33);
     9         list.add(44);
    10         list.add(11);
    11         list.add(15);
    12         list.add(12);
    13         list.add(7);
    14         list.add(3);
    15         System.out.println("list1 :" + list);
    16         //测试ArrayList的'Iterator<E> iterator()'方法的使用
    17         Iterator<Integer> it = list.iterator();
    18         while(it.hasNext()){
    19             System.out.print(it.next() +" ");
    20         }
    21         System.out.println("");
    22         System.out.println("list2 :" + list);
    23         it.remove();
    24         System.out.println("list3 :" + list);
    25     }
    26 }
    27 
    28 运行结果:
    29 list1 :[22, 33, 44, 11, 15, 12, 7, 3]
    30 22 33 44 11 15 12 7 3 
    31 list2 :[22, 33, 44, 11, 15, 12, 7, 3]
    32 list3 :[22, 33, 44, 11, 15, 12, 7]

    源代码如下:(这个方法直接用了一个内部类来帮助实现功能)

    1     public Iterator<E> iterator() {
    2         //每次调用iterator()方法都会去new一个Itr类
    3         return new Itr();
    4     }
     1     private class Itr implements Iterator<E> {
     2         //下一个返回元素的索引
     3         int cursor;       // index of next element to return
     4         //最近返回元素的索引
     5         int lastRet = -1; // index of last element returned; -1 if no such
     6         //fast-fail标记标识
     7         int expectedModCount = modCount;
     8 
     9        //如果列表仍有元素可以迭代,则返回true
    10         public boolean hasNext() {
    11             return cursor != size;
    12         }
    13 
    14         //返回迭代的下一个元素
    15         @SuppressWarnings("unchecked")
    16         public E next() {
    17             //检查fast-fail机制
    18             checkForComodification();
    19             int i = cursor;
    20             if (i >= size)
    21                 throw new NoSuchElementException();
    22             Object[] elementData = ArrayList.this.elementData;
    23             if (i >= elementData.length)
    24                 throw new ConcurrentModificationException();
    25             cursor = i + 1;
    26             return (E) elementData[lastRet = i];
    27         }
    28         //从迭代器指向的列表中移除迭代器返回的最后一个元素
    29         public void remove() {
    30             //检查迭代器是否返回过元素
    31             if (lastRet < 0)
    32                 throw new IllegalStateException();
    33             //检查fast-fail机制
    34             checkForComodification();
    35 
    36             try {
    37                 //删除列表中最后返回的那个元素
    38                 ArrayList.this.remove(lastRet);
    39                 cursor = lastRet;
    40                 lastRet = -1;
    41                 expectedModCount = modCount;
    42             } catch (IndexOutOfBoundsException ex) {
    43                 throw new ConcurrentModificationException();
    44             }
    45         }
    46 
    47         //检查fast-fail机制标识
    48         final void checkForComodification() {
    49             if (modCount != expectedModCount)
    50                 throw new ConcurrentModificationException();
    51         }
    52     }

    (2)ListIterator<E> listIterator()

    功能: 返回列表的ListIterator实例

    源代码如下:(这个方法直接用了一个内部类来帮助实现功能)

    1 public ListIterator<E> listIterator() {
    2    return new ListItr(0);
    3 }

    (3)ListIterator<E> listIterator(int index)

    功能: 返回列表的ListIterator实例

    源代码如下:(这个方法直接用了一个内部类来帮助实现功能)

    1     public ListIterator<E> listIterator(int index) {
    2         //首先检查index是否合法,如果不合法则抛出异常
    3         if (index < 0 || index > size)
    4             throw new IndexOutOfBoundsException("Index: "+index);
    5          //创建一个ListItr对象
    6          return new ListItr(index);
    7     }
     1     private class ListItr extends Itr implements ListIterator<E> {
     2        /*带参数构造函数*/ 
     3        ListItr(int index) {
     4             super();
     5             cursor = index;
     6         }
     7         //如果以逆向遍历列表,列表迭代器有多个元素,则返回true
     8         public boolean hasPrevious() {
     9             return cursor != 0;
    10         }
    11         //返回对next的后续调用所返回的元素的索引
    12         public int nextIndex() {
    13             return cursor;
    14         }
    15         //返回对previous的后续调用所返回元素的索引
    16         public int previousIndex() {
    17             return cursor - 1;
    18         }
    19         //返回列表中前一个元素
    20         @SuppressWarnings("unchecked")
    21         public E previous() {
    22             //检查fast-fail机制标识
    23             checkForComodification();
    24             //返回索引下标值减1
    25             int i = cursor - 1;
    26             if (i < 0)
    27                 throw new NoSuchElementException();
    28             Object[] elementData = ArrayList.this.elementData;
    29             if (i >= elementData.length)
    30                 throw new ConcurrentModificationException();
    31             cursor = i;
    32             //返回元素
    33             return (E) elementData[lastRet = i];
    34         }
    35         //用指定元素替换next或者previous返回的最后一个元素
    36         public void set(E e) {
    37             if (lastRet < 0)
    38                 throw new IllegalStateException();
    39             //检查fast-fail机制
    40             checkForComodification();
    41 
    42             try {
    43                 ArrayList.this.set(lastRet, e);
    44             } catch (IndexOutOfBoundsException ex) {
    45                 throw new ConcurrentModificationException();
    46             }
    47         }
    48         //将指定的元素插入列表
    49         public void add(E e) {
    50             //检查fast-fail机制
    51             checkForComodification();
    52 
    53             try {
    54                 int i = cursor;
    55                 //添加元素e到计划中
    56                 ArrayList.this.add(i, e);
    57                 cursor = i + 1;
    58                 lastRet = -1;
    59                 expectedModCount = modCount;
    60             } catch (IndexOutOfBoundsException ex) {
    61                 throw new ConcurrentModificationException();
    62             }
    63         }
    64     }

    (4)List<E> subList(int fromIndex, int toIndex)

    功能: 返回列表从索引位置fromIndex到toIndex之间元素组成的子列表

    源代码如下:

      1 public List<E> subList(int fromIndex, int toIndex) {
      2         //检查参数fromIndex和toIndex是否合法
      3         subListRangeCheck(fromIndex, toIndex, size);
      4         //创建一个SubList对象
      5         return new SubList(this, 0, fromIndex, toIndex);
      6     }
      7 
      8     static void subListRangeCheck(int fromIndex, int toIndex, int size) {
      9         //起始位置fromIndex小于0,则抛出异常
     10         if (fromIndex < 0)
     11             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
     12         //终止位置toIndex大于列表中元素个数size,则抛出异常
     13         if (toIndex > size)
     14             throw new IndexOutOfBoundsException("toIndex = " + toIndex);
     15         //起始位置fromIndex 大于 终止位置toIndex,则抛出异常
     16         if (fromIndex > toIndex)
     17             throw new IllegalArgumentException("fromIndex(" + fromIndex +") > toIndex(" + toIndex + ")");
     18     }
     19 
     20 /*
     21 内部类,为了配合subList方法
     22 */
     23 private class SubList extends AbstractList<E> implements RandomAccess {
     24         private final AbstractList<E> parent;
     25         private final int parentOffset;
     26         private final int offset;
     27         int size;
     28         //构造方法
     29         SubList(AbstractList<E> parent,
     30                 int offset, int fromIndex, int toIndex) {
     31             this.parent = parent;
     32             this.parentOffset = fromIndex;
     33             this.offset = offset + fromIndex;
     34             this.size = toIndex - fromIndex;
     35             this.modCount = ArrayList.this.modCount;
     36         }
     37 
     38         public E set(int index, E e) {
     39             rangeCheck(index);
     40             checkForComodification();
     41             E oldValue = ArrayList.this.elementData(offset + index);
     42             ArrayList.this.elementData[offset + index] = e;
     43             return oldValue;
     44         }
     45 
     46         public E get(int index) {
     47             rangeCheck(index);
     48             checkForComodification();
     49             return ArrayList.this.elementData(offset + index);
     50         }
     51 
     52         public int size() {
     53             checkForComodification();
     54             return this.size;
     55         }
     56 
     57         public void add(int index, E e) {
     58             rangeCheckForAdd(index);
     59             checkForComodification();
     60             parent.add(parentOffset + index, e);
     61             this.modCount = parent.modCount;
     62             this.size++;
     63         }
     64 
     65         public E remove(int index) {
     66             rangeCheck(index);
     67             checkForComodification();
     68             E result = parent.remove(parentOffset + index);
     69             this.modCount = parent.modCount;
     70             this.size--;
     71             return result;
     72         }
     73 
     74         protected void removeRange(int fromIndex, int toIndex) {
     75             checkForComodification();
     76             parent.removeRange(parentOffset + fromIndex,
     77                                parentOffset + toIndex);
     78             this.modCount = parent.modCount;
     79             this.size -= toIndex - fromIndex;
     80         }
     81 
     82         public boolean addAll(Collection<? extends E> c) {
     83             return addAll(this.size, c);
     84         }
     85 
     86         public boolean addAll(int index, Collection<? extends E> c) {
     87             rangeCheckForAdd(index);
     88             int cSize = c.size();
     89             if (cSize==0)
     90                 return false;
     91 
     92             checkForComodification();
     93             parent.addAll(parentOffset + index, c);
     94             this.modCount = parent.modCount;
     95             this.size += cSize;
     96             return true;
     97         }
     98 
     99         public Iterator<E> iterator() {
    100             return listIterator();
    101         }
    102 
    103         public ListIterator<E> listIterator(final int index) {
    104             checkForComodification();
    105             rangeCheckForAdd(index);
    106             final int offset = this.offset;
    107 
    108             return new ListIterator<E>() {
    109                 int cursor = index;
    110                 int lastRet = -1;
    111                 int expectedModCount = ArrayList.this.modCount;
    112 
    113                 public boolean hasNext() {
    114                     return cursor != SubList.this.size;
    115                 }
    116 
    117                 @SuppressWarnings("unchecked")
    118                 public E next() {
    119                     checkForComodification();
    120                     int i = cursor;
    121                     if (i >= SubList.this.size)
    122                         throw new NoSuchElementException();
    123                     Object[] elementData = ArrayList.this.elementData;
    124                     if (offset + i >= elementData.length)
    125                         throw new ConcurrentModificationException();
    126                     cursor = i + 1;
    127                     return (E) elementData[offset + (lastRet = i)];
    128                 }
    129 
    130                 public boolean hasPrevious() {
    131                     return cursor != 0;
    132                 }
    133 
    134                 @SuppressWarnings("unchecked")
    135                 public E previous() {
    136                     checkForComodification();
    137                     int i = cursor - 1;
    138                     if (i < 0)
    139                         throw new NoSuchElementException();
    140                     Object[] elementData = ArrayList.this.elementData;
    141                     if (offset + i >= elementData.length)
    142                         throw new ConcurrentModificationException();
    143                     cursor = i;
    144                     return (E) elementData[offset + (lastRet = i)];
    145                 }
    146 
    147                 public int nextIndex() {
    148                     return cursor;
    149                 }
    150 
    151                 public int previousIndex() {
    152                     return cursor - 1;
    153                 }
    154 
    155                 public void remove() {
    156                     if (lastRet < 0)
    157                         throw new IllegalStateException();
    158                     checkForComodification();
    159 
    160                     try {
    161                         SubList.this.remove(lastRet);
    162                         cursor = lastRet;
    163                         lastRet = -1;
    164                         expectedModCount = ArrayList.this.modCount;
    165                     } catch (IndexOutOfBoundsException ex) {
    166                         throw new ConcurrentModificationException();
    167                     }
    168                 }
    169 
    170                 public void set(E e) {
    171                     if (lastRet < 0)
    172                         throw new IllegalStateException();
    173                     checkForComodification();
    174 
    175                     try {
    176                         ArrayList.this.set(offset + lastRet, e);
    177                     } catch (IndexOutOfBoundsException ex) {
    178                         throw new ConcurrentModificationException();
    179                     }
    180                 }
    181 
    182                 public void add(E e) {
    183                     checkForComodification();
    184 
    185                     try {
    186                         int i = cursor;
    187                         SubList.this.add(i, e);
    188                         cursor = i + 1;
    189                         lastRet = -1;
    190                         expectedModCount = ArrayList.this.modCount;
    191                     } catch (IndexOutOfBoundsException ex) {
    192                         throw new ConcurrentModificationException();
    193                     }
    194                 }
    195 
    196                 final void checkForComodification() {
    197                     if (expectedModCount != ArrayList.this.modCount)
    198                         throw new ConcurrentModificationException();
    199                 }
    200             };
    201         }
    202 
    203         public List<E> subList(int fromIndex, int toIndex) {
    204             subListRangeCheck(fromIndex, toIndex, size);
    205             return new SubList(this, offset, fromIndex, toIndex);
    206         }
    207 
    208         private void rangeCheck(int index) {
    209             if (index < 0 || index >= this.size)
    210                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    211         }
    212 
    213         private void rangeCheckForAdd(int index) {
    214             if (index < 0 || index > this.size)
    215                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    216         }
    217 
    218         private String outOfBoundsMsg(int index) {
    219             return "Index: "+index+", Size: "+this.size;
    220         }
    221 
    222         private void checkForComodification() {
    223             if (ArrayList.this.modCount != this.modCount)
    224                 throw new ConcurrentModificationException();
    225         }
    226     }
    View Code

    -------------------------------------------------------------------------------

    java.util.ArrayList系列文章                                                                

    java.util.ArrayList<E>(1)  java.util.ArrayList<E>(2)  java.util.ArrayList<E>(3)

    java.util.ArrayList<E>(4)  java.util.ArrayList<E>(5)  java.util.ArrayList<E>(6)

    相关知识                                                                                              

    java.util.Collection<E>   java.util.AbstractCollection<E>   java.util.List<E>

    java.util.AbstractList<E>   java.util.Iterator<E>   java.util.ListIterator<E>

    Java中的标记接口   迭代器模式   Java中的深拷贝和浅拷贝  java.util.Arrays

  • 相关阅读:
    职业的选择
    事务的隔离性理解
    浅谈CSS和JQuery实现鼠标悬浮图片放大效果
    jvm 类加载器
    jvm 类加载
    Spring 启动 Bean加载流程
    优雅的博客园客户端发布Forms版啦。
    Xamarin Forms中WebView的自适应高度
    2017回顾与2018目标
    优雅的博客园Android客户端
  • 原文地址:https://www.cnblogs.com/xinhuaxuan/p/6354179.html
Copyright © 2020-2023  润新知