博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构之--单链表MyArrayList
阅读量:6456 次
发布时间:2019-06-23

本文共 5506 字,大约阅读时间需要 18 分钟。

仿照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 
手写的这个顺序表支持泛型 7 */ 8 public class MyArrayList
implements Iterable
{ 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 @Override103 public Iterator
iterator() {104 return new MyArrayListIterator();105 }106 107 // 内部类的形式 定义一个自己的 迭代器 内部类 可以方便的访问 外部类的 数据成员108 private class MyArrayListIterator implements Iterator
109 {110 private int current = 0;111 112 @Override113 public boolean hasNext() {114 return current < size();115 }116 117 @Override118 public AnyType next() {119 if(!hasNext())120 throw new NoSuchElementException();121 122 return theItems[current++];123 }124 125 @Override126 public void remove() {127 MyArrayList.this.remove(--current); // 创建调用内部类的方法128 }129 130 }131 132 public static void main(String[] args) {133 MyArrayList
list = new MyArrayList
();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
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的,只能访问被嵌套类中的静态属性和静态方法。

转载于:https://www.cnblogs.com/OliverZhang/p/6596897.html

你可能感兴趣的文章
JMeter—断言
查看>>
C++的新类创建:继承与组合
查看>>
odoo 权限设置
查看>>
asp操作access提示“无法从指定的数据表中删除”
查看>>
git bash 风格调整
查看>>
bzoj4589 Hard Nim
查看>>
java实现pdf旋转_基于Java实现PDF文本旋转倾斜
查看>>
python time库3.8_python3中datetime库,time库以及pandas中的时间函数区别与详解
查看>>
贪吃蛇java程序简化版_JAVA简版贪吃蛇
查看>>
poi java web_WebPOI JavaWeb 项目 导出excel表格(.xls) Develop 238万源代码下载- www.pudn.com...
查看>>
oracle报1405,【案例】Oracle报错ORA-15054 asm diskgroup无法mount的解决办法
查看>>
linux 脚本map,Linux Shell Map的用法详解
查看>>
如何在linux系统下配置共享文件夹,如何在windows和Linux系统之间共享文件夹.doc
查看>>
linux操作系统加固软件,系统安全:教你Linux操作系统的安全加固
查看>>
linux中yum源安装dhcp,24.Linux系统下动态网络源部署方法(dhcpd)
查看>>
ASP.NET性能优化之分布式Session
查看>>
TaffyDB Introduction
查看>>
转载:《TypeScript 中文入门教程》 16、Symbols
查看>>
JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记4
查看>>
C#技术------垃圾回收机制(GC)
查看>>