ArrayList类
2016-05-01 13:56
375 查看
以数组实现。节约空间,但数组有容量限制。超出限制时会增加50%容量,用System.arraycopy()复制到新的数组,因此最好能给出数组大小的预估值。默认第一次插入元素时创建大小为10的数组。
按数组下标访问元素—get(i)/set(i,e) 的性能很高,这是数组的基本优势。直接在数组末尾加入元素—add(e)的性能也高,但如果按下标插入、删除元素—add(i,e), remove(i), remove(e),则要用System.arraycopy()来移动部分受影响的元素,性能就变差了,这是基本劣势。
ArrayList重要的一点是它的自动扩容,即我们常说的“动态数组”。
下面将代码示例ArrayList的实现,为与类库中的类区别出来,这里把该类命名为MyArrayList。不提供MyCollection或MyList接口,MyArrayList是独立的。ArrayList类的实现类的要点如下:
1. MyArrayList将保持基础数组,数组容量,以及存储在MyArrayList中的当前项数。
2. MyArrayList将提供一种机制以改变基础数组的容量。通过获得一个新数组,将老数组拷贝到新数组中来改变数组的容量,允许虚拟机回收老数组。
3. MyArrayList将提供get和set的实现。
4. MyArrayList将提供基本的操作例程,如size、isEmpty和clear,它们是典型的单行程序;还提供remove,以及两种不同版本的add。如果数组的大小和容量相同,那么这两个add例程将增加容量。
5. MyArrayList将提供一个实现Iterator接口的类。这个类将存储迭代系列中的下一项的下标,并提供next、hasNext和remove等方法的实现。MyArrayList的迭代器方法直接返回实现Iterator接口的该类的新构造器的实例。
下面写基本类MyArrayList,想它的Collection API的对应类一样,存在某种错误检测以保证合理的限界,但为了把专注于编写迭代器的基本方面内容,这里不检测可能使迭代器无效的结构上的修改,也不检测非法的迭代器remove方法。代码清单如下:
如代码所示,MyArrayList把大小及数组作为其数据成员进行存储。然后接着是几个短例程clear、size、trimToSize、isEmpty、get以及set的实现。
接着是ensureCapacity例程,容量的扩充是用于早先描述的相同的方法来完成的:存储对原始数组的一个引用,为新数组分配内存,并将旧内容拷贝到新数组中。例程ensureCapacity也可以用于收缩基础数组,不过要指定的新容量至少和原大小一样才适用。否则,ensureCapacity的要求将被忽略。由于泛型数组的创建是非法的,所以要创建一个泛型类型限界的数组,然后使用一个数组进行类型转换。这会产生一个编译器警告,但在泛型集合的实现中是不可避免的。
remove方法类似与add,只是那些位于指定位置上或指定位置后的元素向低移动到一个位置。
剩下的例程处理iterator方法和相关迭代器类的实现。iterator方法直接返回ArrayListIterator类的一个实例, 该类是一个实现Iterator接口的类。ArrayListIterator存储当前位置的概念,提供hasNext、next和remove的实现。当前位置表示要被查看的下一元素(的数组下标),因此初始时当前位置为0。
按数组下标访问元素—get(i)/set(i,e) 的性能很高,这是数组的基本优势。直接在数组末尾加入元素—add(e)的性能也高,但如果按下标插入、删除元素—add(i,e), remove(i), remove(e),则要用System.arraycopy()来移动部分受影响的元素,性能就变差了,这是基本劣势。
ArrayList重要的一点是它的自动扩容,即我们常说的“动态数组”。
下面将代码示例ArrayList的实现,为与类库中的类区别出来,这里把该类命名为MyArrayList。不提供MyCollection或MyList接口,MyArrayList是独立的。ArrayList类的实现类的要点如下:
1. MyArrayList将保持基础数组,数组容量,以及存储在MyArrayList中的当前项数。
2. MyArrayList将提供一种机制以改变基础数组的容量。通过获得一个新数组,将老数组拷贝到新数组中来改变数组的容量,允许虚拟机回收老数组。
3. MyArrayList将提供get和set的实现。
4. MyArrayList将提供基本的操作例程,如size、isEmpty和clear,它们是典型的单行程序;还提供remove,以及两种不同版本的add。如果数组的大小和容量相同,那么这两个add例程将增加容量。
5. MyArrayList将提供一个实现Iterator接口的类。这个类将存储迭代系列中的下一项的下标,并提供next、hasNext和remove等方法的实现。MyArrayList的迭代器方法直接返回实现Iterator接口的该类的新构造器的实例。
下面写基本类MyArrayList,想它的Collection API的对应类一样,存在某种错误检测以保证合理的限界,但为了把专注于编写迭代器的基本方面内容,这里不检测可能使迭代器无效的结构上的修改,也不检测非法的迭代器remove方法。代码清单如下:
package com.afy.datastructures.collection; import java.util.Iterator; import javax.sql.rowset.JdbcRowSet; import com.sun.glass.ui.Size; public class MyArrayList<AnyType> implements Iterable<AnyType> { private static final int DEFAULT_CAPACITY = 10; private int theSize; private AnyType [] theItems; public MyArrayList(){ doClear(); } private void doClear() { theSize = 0; ensureCapacity(DEFAULT_CAPACITY ); } private int size() { return theSize; } public boolean isEmpty(){ return size() ==0; } public void trimToSize(){ ensureCapacity(size()); } public AnyType get(int idx){ if (idx<0 || idx>=size()) throw new ArrayIndexOutOfBoundsException(); return theItems[idx]; } public AnyType set(int idx , AnyType newVal){ if (idx < 0 || idx >=size()) throw new ArrayIndexOutOfBoundsException(); AnyType old = theItems[idx]; theItems[idx] = newVal; return old; } private void ensureCapacity(int newCapacity) { if (newCapacity<theSize) return; AnyType [] old = theItems; theItems = (AnyType[]) new Object[newCapacity]; for(int i = 0;i<size();i++) theItems[i] = old[i]; } public boolean add(AnyType x){ add(size(),x); return true; } public void add(int idx, AnyType x) { if (theItems.length==size()) { ensureCapacity(size()*2+1); for(int i=theSize;i>idx;i--) theItems[i] = theItems[i-1]; theItems[idx]=x; theSize++; } } public AnyType remove(int idx) { AnyType removeItem = theItems[idx]; for(int i = idx; i<size()-1;i++) theItems[i] = theItems[i+1]; theSize--; return removeItem; } @Override public Iterator<AnyType> iterator() { return new ArrayListIterator(); } private class ArrayListIterator implements java.util.Iterator<AnyType>{ private int current = 0; public boolean hasNext(){ return current < size(); } public AnyType next(){ if (!hasNext()) { throw new java.util.NoSuchElementException(); } return theItems[current++]; } public void remove(){ MyArrayList.this.remove(--current); } } }
如代码所示,MyArrayList把大小及数组作为其数据成员进行存储。然后接着是几个短例程clear、size、trimToSize、isEmpty、get以及set的实现。
接着是ensureCapacity例程,容量的扩充是用于早先描述的相同的方法来完成的:存储对原始数组的一个引用,为新数组分配内存,并将旧内容拷贝到新数组中。例程ensureCapacity也可以用于收缩基础数组,不过要指定的新容量至少和原大小一样才适用。否则,ensureCapacity的要求将被忽略。由于泛型数组的创建是非法的,所以要创建一个泛型类型限界的数组,然后使用一个数组进行类型转换。这会产生一个编译器警告,但在泛型集合的实现中是不可避免的。
remove方法类似与add,只是那些位于指定位置上或指定位置后的元素向低移动到一个位置。
剩下的例程处理iterator方法和相关迭代器类的实现。iterator方法直接返回ArrayListIterator类的一个实例, 该类是一个实现Iterator接口的类。ArrayListIterator存储当前位置的概念,提供hasNext、next和remove的实现。当前位置表示要被查看的下一元素(的数组下标),因此初始时当前位置为0。
相关文章推荐
- setsockopt中参数之SO_REUSEADDR的意义
- 1.关于Box2d
- HTML本地数据库indexDataBase的使用示例
- 2016年4月16日作业(项目整体管理、项目范围管理)
- 业务、产品、技术、团队之间的关系(业务产品篇)
- Google网络请求框架Volley源码浅析(三)
- 2016年中南大学校赛镜像赛
- ios拼图游戏(二)之长按手势和拖动手势的区别
- Java基础、面向对象总结
- Java-Android
- Java核心知识点-路径获取
- 《Linux内核分析》 学习总结
- 图片上传后及时预览
- redis在windows下安装和PHP中使用
- 时间复杂度和空间复杂度详解
- JAVA设计模式之单例模式:内部静态类
- Java 高效并发
- hrbust/哈理工oj 2028 小猴和冒泡2【归并排序】
- BZOJ2038 小z的袜子
- ZOJ1654 Place the Robots