数据结构之--单链表MyArrayList

仿照Java集合类库中的ArrayList,自己手动写了一个MyArrayList,内部使用一个数组来维护。具体的adt描述如下

isEmpty()    判断是否为空

size()      获取当前存储的元素个数

clear()     清空当前的所有元素

set(idx, e)    重置指定位置的元素

ensureCapacity(newCapacity)  指定底层数组的大小

add(e)      添加一个元素,默认在尾部

add(idx, e)    在指定位置添加一个元素

remove(idx)    删除指定位置的元素

iterator()      返回相应的迭代器

  1 /**
  2  * 手写的一个MyArraylist实现ArrayList的常规操作,并且也实现了迭代器
  3  * 实现迭代器操作,必须要实现Iteratable接口
  4  * @author Administrator
  5  *
  6  * @param <AnyType> 手写的这个顺序表支持泛型
  7  */
  8 public class MyArrayList<AnyType> implements Iterable<AnyType>{
  9     private static final int DEFAULT_CAPACITY = 10;    //默认的 大小为 10
 10     
 11     private int thisSize ;    // 当前已经存入的元素的个数
 12     private AnyType[] theItems;    //定义一个数组用来存储元素, 而且是一种懒汉模式来维护的
 13     
 14     public MyArrayList(){
 15         clear();
 16     }
 17     
 18     /**
 19      * 清空这个链表
 20      */
 21     public void clear()
 22     {
 23         thisSize = 0;
 24         ensureCapacity(DEFAULT_CAPACITY);
 25     }
 26     
 27     public int size(){
 28         return thisSize;
 29     }
 30     public boolean isEmpty()
 31     {
 32         return size()==0;    // 当thisSize==0说明为空链表
 33     }
 34     public void trimToSize()
 35     {
 36         ensureCapacity(size());
 37     }
 38     
 39     public AnyType get(int idx)
 40     {
 41         if(idx < 0 || idx >= size())
 42             throw new ArrayIndexOutOfBoundsException();    //    抛出数组越界的异常
 43         return theItems[ idx ];
 44     }
 45     /*
 46      * 重置指定位置idx处的元素 为 newVal
 47      */
 48     public AnyType set(int idx, AnyType newVal)
 49     {
 50         if(idx <= 0 || idx >= size())
 51             throw new ArrayIndexOutOfBoundsException();
 52         AnyType old = theItems[ idx ];
 53         theItems[idx] = newVal;
 54         return old;
 55     }
 56     
 57     public void ensureCapacity( int newCapacity )
 58     {
 59         if(newCapacity < thisSize)// 不需要 修改数组的大小
 60             return ;
 61         
 62         AnyType[] old = theItems;    //先把原来的数组记录下来
 63 //        theItems = new AnyType[newCapacity]; 注意了 不能这样创建一个泛型的数组 向下面那样操作就行了
 64         theItems = (AnyType[]) new Object[ newCapacity ];
 65         for (int i = 0; i < size(); i++) {
 66             theItems[i] = old[i];
 67         }
 68     }
 69     
 70     // 默认在尾部插入
 71     public boolean add(AnyType x)
 72     {
 73         add(size(), x);
 74         return true;
 75     }
 76     
 77     public void add(int idx, AnyType x)
 78     {
 79         if(theItems.length == size())
 80             ensureCapacity(size()*2 + 1);    //一旦size不够 就扩容两倍
 81         // 先把 [idx, size]的元素向后移动
 82         for(int i = thisSize; i > idx; i--)// 为什么 不是 i = thisSieze - 1; 因为初始 thisSize=0的时候 会出现数组越界的情况
 83             theItems[i] = theItems[i-1];
 84         theItems[idx] = x;
 85         thisSize ++;
 86     }
 87     
 88     public AnyType remove(int idx)
 89     {
 90         if(idx <= 0 || idx > size())
 91             throw new ArrayIndexOutOfBoundsException();
 92         AnyType removeItem = theItems[idx-1];
 93         // 吧[idx+1, size]元素想做移动1
 94         for(int i = idx-1; i < size(); i++)
 95             theItems[i] = theItems[i+1];
 96         
 97         thisSize --;
 98         return removeItem;
 99     }
100     
101     
102     @Override
103     public Iterator<AnyType> iterator() {
104         return new MyArrayListIterator();
105     }
106     
107     // 内部类的形式 定义一个自己的 迭代器  内部类 可以方便的访问 外部类的 数据成员
108     private class MyArrayListIterator implements Iterator<AnyType>
109     {
110         private int current = 0;
111         
112         @Override
113         public boolean hasNext() {
114             return current < size();
115         }
116 
117         @Override
118         public AnyType next() {
119             if(!hasNext())
120                 throw new NoSuchElementException();
121             
122             return theItems[current++];
123         }
124 
125         @Override
126         public void remove() {
127             MyArrayList.this.remove(--current);    // 创建调用内部类的方法
128         }
129         
130     }
131     
132     public static void main(String[] args) {
133         MyArrayList<Integer> list = new MyArrayList<Integer>();
134         
135         System.out.println(list.isEmpty());
136         System.out.println(list.size());
137         
138         list.add(1);
139         list.add(2);
140         list.add(3);
141         list.add(4);
142         System.out.println(list.isEmpty());
143         System.out.println(list.size());
144         
145         System.out.println(list.remove(2));
146         
147         System.out.println(list.size());
148         
149         Iterator<Integer> it = list.iterator();
150         while(it.hasNext())
151             System.out.print(it.next()+", ");
152         System.out.println();
153     }
154 
155 }

 line103~line130其实是很有内容的,这里把ArrayListIterator定义成了一个内部类。

private class ArrayListIterator implements Iterator<AnyType>{

  private int current = 0;

  public boolean hasNext()

  {return current < size()}  //current < MyArrayList.this.size()

  ………………

  public void remove()

  {MyArraylList.this.remove(--current);}  // 为了消除歧义,就不能简写了

},

上面其实都是内部类(Internal class),内部类里面可以直接访问外部类的属性和方法,其实在内部类中调用外部类的方法和属性时,实际上应当是带上外部类的一个引用比如应当是current < MyArrayList.this.size(),内部类的一大好处是允许程序员简写成current < size(),简写的前提是内部类和外部类没有回引起歧义的同名方法或者同名属性,如果会引起歧义时就不能再简写了,比如下面的 remove方法,内部类ArrayListIterator和外部类MyArrayList都有这个方法,那么在内部类总调用外部类的remove方法时,就不能简写了,应当写成MyArrayList.this.remove(--current);

private static class ArrayListIterator implements Iterator<AnyType>{

}

这种定义情况和上一中乍一看差不多,只是多了一个static关键字而已,这时ArrayListIterator就不在是一个内部类,摇身一变成了一个嵌套类(Nest额的 Class)。嵌套类因为是一个static的,只能访问被嵌套类中的静态属性和静态方法。

posted @ 2017-03-21 21:45  zhangoliver  阅读(716)  评论(0编辑  收藏  举报