目录
构造方法的重载,对容器进行初始化
向容器中增加元素
打印容器中的元素
判断索引是否合法
获取指定下标的元素
通过指定元素来删除容器中的元素
通过指定下标删除容器中的元素
插入元素,在pos个位置,这里是从1开始计数的
Java中的ArrayList在底层实际上使用数组实现的,它拥有和数组相似的特性,容易存取,不容易插入或者删除。
下面来看看如何手动实现一个ArrayLis,实现的ArrayList中增加有泛型。
首先创建一个名为hxzArrayList的类,里面有我们待实现的方法:
class hxzArrayList<E>{
Object[] elementData;//定义容器中的属性
private int size;//容器中元素的个数
private static final int DEFAULT_CAPACITY = 10;//在未指定容器的情况下,容器的默认大小
public hxzArrayList();//构造方法的重载,对容器进行初始化
public hxzArrayList(int capacity);
public void arraylistAdd(E element);//向容器中增加元素
public String toString();//打印容器中的元素
public void arrayListRemove(E element);//删除容器中的元素
public void arrayListRemove(int index);
public void arrayInsert(int pos , E e);//插入元素
public int getSize();//获得元素的个数
public void set(E element , int index);//替换指定下标的元素
public E get(int index);//获得指定下标的元素
public void checkIndex(int index);//检查下表是否合法
}
构造方法的重载,对容器进行初始化
public hxzArrayList() {
elementData = new Object[DEFAULT_CAPACITY];
}
public hxzArrayList(int capacity) {
if(capacity<0) {
throw new RuntimeException("容器的容量不能为负数!");//手动抛出异常
}else if(capacity==0) {
elementData = new Object[DEFAULT_CAPACITY];
}else {
elementData = new Object[capacity];
}
}
向容器中增加元素
public void arraylistAdd(E element) {
//当元素个数(size)与数组的长度相等时,要扩容
if(size==elementData.length) {
//把当前数组所有元素拷贝到另一个更大的数组中去
Object[] newArrayList = new Object[elementData.length+(elementData.length>>1)];
System.arraycopy(elementData, 0, newArrayList, 0, elementData.length);
elementData = newArrayList;
}
elementData[size++] = element;
}
打印容器中的元素
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0 ; i<size ; i++) {
sb.append(elementData[i]+",");
}
sb.setCharAt(sb.length()-1,']');
return sb.toString();
}
}
这里我们假设容器内都是String类型的元素,重写toString()方法,创建StringBuffer对象,把容器中元素追加到StringBuffer对象中去。
判断索引是否合法
public void checkIndex(int index) {
if(index<0||index>size)
{
throw new RuntimeException("该索引不合法!");
}
}
获取指定下标的元素
public E get(int index) {
checkIndex(index);
return (E)elementData[index];
}
通过指定元素来删除容器中的元素
public void arrayListRemove(E element) {
for(int i=0 ; i<size ; i++) {//不能使用elementData.length
if(element.equals(get(i))) {
arrayListRemove(i);
}
}
}
注意:for(int i=0 ; i<size ; i++) 在for循环的判断语句中不能把size用elementData.length代替。
这是因为:当容器中元素的个数(size)小于数组的长度时,随着for循环,i 的值不断增大,当i增大到比size大时,检查下标是否合法的checkIndex方法就会抛出异常。
而且,比较元素的值是否与指定元素相等时,记住要用equals方法,而不能是==!
通过指定下标删除容器中的元素
public void arrayListRemove(int index) {
int move = elementData.length-index-1;
if(move>0)
System.arraycopy(elementData, index+1, elementData, index, move);
elementData[--size] = null;
}
插入元素,在pos个位置,这里是从1开始计数的
public void arrayInsert(int pos , E e) {
Object[] str1 = new Object[size+1];
System.arraycopy(elementData, 0, str1, 0, size);
System.arraycopy(str1, pos-1, str1, pos, size-pos);
str1[pos-1] = e;
elementData = str1;
size++;
}
插入和删除的本质都是通过数组的复制来实现的。