Java数据结构 ArrayList的简单MyArrayList编写

编写MyArrayList的基本思路

1.根据ArrayList,MyArrayList需要有clear(),size(),isEmpty(),get(index),set(index ,data),add(data),add(index , data),remove(index)方法。

2.MyArrayList需要提供一个实现Iterator接口的类,这个类current存储迭代序列下一项的下标,并重写hasnext()和next()方法,新增remove()方法,MyArrayList的迭代器方法直接返回实现Iterator接口的类新构造的实例。

3.因为ArrayList是可增的,所以MyArrayList将提供ensureCapacity()方法来改变基础数组的容量,通过新建一个数组来存储原数组的数据,然后将原数组引用给一个新的容量为Capacity的新数组,再将原数组数据拷贝到新数组。

完整代码如下:

package com.MyArrayList;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyArrayList<AnyType> implements Iterable<AnyType> {
	// 定义初始list大小
	// 定义数组
	// 定义数组大小
	private static final int DEFAULT_CAPACITY = 10;
	private AnyType[] theItems;
	private int thesize;
	// 定义MyArrayList的方法,分别是clear(),size(),get(),set(),isEmpty(),ensureCapaciy(),add(),remove()

	// 编写构造函数
	public MyArrayList() {
		clear();
	}

	// 清空list
	public void clear() {
		thesize = 0;
		ensureCapacity(DEFAULT_CAPACITY);
	}

	public int size() {
		return thesize;
	}

	// 判断list是否为空
	public boolean isEmpty() {
		return size() == 0;
	}

	// 获取到指定索引的list
	public AnyType get(int index) {
		if (index < 0 || index > thesize) {
			throw new ArrayIndexOutOfBoundsException();
		}
		return theItems[index];
	}

	// 将list中索引为index的元素设定为指定元素
	public AnyType set(int index, AnyType data) {
		if (index < 0 || index > thesize) {
			throw new ArrayIndexOutOfBoundsException();
		}
		AnyType old = theItems[index];
		theItems[index] = data;
		return old;
	}

	// 扩充此数组容量,即list容量
	@SuppressWarnings("unchecked")
	private void ensureCapacity(int newCapacity) {
		// 当扩充的容量本身比原list小时
		if (newCapacity < size()) {
			return;
		}
		// 创建一个数组保存原数组的数据
		AnyType[] old = theItems;
		// 将theItem引用给一个新建的容量为newCapacity的数组
		theItems = (AnyType[]) new Object[newCapacity];
		// 将原数据复制给theItems,
		// 注意这里不是old.length而是size(),因为构造函数,所以theItems的大小是10,而size()不一定是
		for (int i = 0; i < size(); i++) {
			theItems[i] = old[i];
		}
	}

	// 在list尾部新添一个元素
	public boolean add(AnyType x) {
		add(size(), x);
		return true;
	}

	// 将元素新添到指定索引
	private void add(int index, AnyType x) {
		if (theItems.length == size()) {
			ensureCapacity(size() * 2 + 1);
		}
		for (int i = thesize; i > index; i--) {
			theItems[i] = theItems[i - 1];
		}
		theItems[index] = x;
		thesize++;
	}

	// 将指定索引index元素移除
	public AnyType remove(int index) {
		AnyType removedata = theItems[index];
		for (int i = index; i < size() - 1; i++) {
			theItems[i] = theItems[i + 1];
		}
		thesize--;
		return removedata;
	}

	public Iterator<AnyType> iterator() {
		return new ArrayListIterator();
	}

	private class ArrayListIterator implements Iterator<AnyType> {

		public int current = 0;

		public boolean hasNext() {
			return current < size();
		}

		public AnyType next() {
			if (!hasNext()) {
				throw new NoSuchElementException();
			}
			return theItems[current++];
		}

		public void remove() {
			MyArrayList.this.remove(--current);
		}
	}
}

下面将一一分析其中比较重要的方法:

private static final int DEFAULT_CAPACITY = 10;
	private AnyType[] theItems;
	private int thesize;

     这里定义了一个静态常量 DEAULT_CAPACITY来赋值初始数组大小,theItem则为实现list的容器,thesize为list的大小。

// 编写构造函数
	public MyArrayList() {
		clear();
	}
// 清空list,并将list大小初始化
	public void clear() {
		thesize = 0;
		ensureCapacity(DEFAULT_CAPACITY);
	}
// 扩充此数组容量,即list容量
	@SuppressWarnings("unchecked")
	private void ensureCapacity(int newCapacity) {
		// 当扩充的容量本身比原list小时
		if (newCapacity < size()) {
			return;
		}
		// 创建一个数组保存原数组的数据
		AnyType[] old = theItems;
		// 将theItem引用给一个新建的容量为newCapacity的数组
		theItems = (AnyType[]) new Object[newCapacity];
		// 将原数据复制给theItems,
		// 注意这里不是old.length而是size(),因为构造函数,所以theItems的大小是10,而size()大小不一定是。
		for (int i = 0; i < size(); i++) {
			theItems[i] = old[i];
		}
	}

       这里构造函数调用clear()方法起到的是一个list初始化的作用,通过clea()方法来调用ensureCapacity(DEFAULT_CAPACITY)来将数组清空,因为thesize设为0则在ensureCapacity()方法中拷贝数组的循环不会执行,新数组的所有值自然为空。

private void add(int index, AnyType x) {
		if (theItems.length == size()) {
			ensureCapacity(size() * 2 );
		}
		for (int i = thesize; i > index; i--) {
			theItems[i] = theItems[i - 1];
		}
		theItems[index] = x;
		thesize++;
	}

        当list中的元素数量已经达到数组的容量时,则要进行容量扩充,因为扩充容量的大小非常昂贵,所以直接将容量大小扩充一倍。

        for循环从thesize,也就是list最后一个元素的后一位,即数组最后一个不为null元素的下一位,然后将前一位数组的元素赋给当前位,循环直到index的后一位,结束循环,再将添加元素赋值给当前索引的数组元素。

public Iterator<AnyType> iterator() {
		return new ArrayListIterator();
	}
private class ArrayListIterator implements Iterator<AnyType> {

		public int current = 0;

		public boolean hasNext() {
			return current < size();
		}

		public AnyType next() {
			if (!hasNext()) {
				throw new NoSuchElementException();
			}
			return theItems[current++];
		}

		public void remove() {
			MyArrayList.this.remove(--current);
		}
	}

       这里创建了一个ArrayListIterator内部类,实现了Iterable<AnyType>的iterator()方法,返回值为一个新构造的ArrayListIterator实例,这样每个集合可以创建并返回个客户一个实现Itetator接口的对象,并将当前位置的概念在list对象内部存储下来。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值