java_模拟实现ArrayList(底层原理分析并实现相关功能)

ArrayList的模拟实现(底层实现原理)

以下部分可能与实际写的方法名不同,但是基本需求还是一样的(添加,删除,插入,判断下标是否越界)

模拟实现ArrayList类(需求分析):

ArrayList属性:
存放int类型的数组 int[] arr;
实际添加元素的个数 int size;
ArrayList构造方法
无参构造方法 public ArrayList() {}
无参构造方法中,用于实例化arr数组,默认开辟10个空间
有参构造方法 public ArrayList(int count) {}
有参构造方法中,根据传入的count,创建指定空间的arr数组
补充:需要实现构造方法之间的调用
ArrayList成员方法
public void add(int value) {}
追加元素方法,把value存入数组arr中,注意考虑扩容的情况
扩容:size == arr.length,则需考虑扩容!
public int get(int index) {}
根据传入的索引,获取该元素索引对应的元素,注意判断index是否越界
public void insert(int index, int value) {}
在arr索引为index的位置,插入value元素,注意考虑扩容的情况和index是否越界
public void deleteElementWithIndex(int index) {}
根据索引index,删除arr数组指定位置的元素,注意判断index是否越界
public int deleteElementWithValue(int value) {}
根据value,找到value在数组arr中的索引,
如果该元素value存在,则删除该元素,并返回该元素所在的索引
如果该元素value不存在,则不对数组做任何操作,返回-1即可

代码如下:

Test01用来测试数据

public class Test01 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add(11);
		list.add(22);
		list.add(33);
		list.add(44);
		System.out.println(list.size());
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		System.out.println("-----------------");
		
		ArrayList list1 = new ArrayList();
		list1.add(1233);
		list1.add(1234);
		list1.add(1235);
		list1.add(1236);
		list1.add(1237);
		list1.add(1238);
		list1.remove(2);
		list1.insert(2, 1235);
		System.out.println(list1.size());
		for (int i = 0; i < list1.size(); i++) {
			System.out.println(list1.get(i));
		}
	}
}

ArrayList用来实现基本功能

public class ArrayList {
	/**
	 * 用于存放数据的数组
	 */
	private int[] elementData;
	/**
	 * 用于保存实际存放元素的个数
	 */
	private int size;
	/**
	 * 获取实际存元素的个数
	 * @return 返回实际存放元素的个数
	 */
	public int size() {
		return this.size;
	}
	/**
	 * 无参构造方法
	 * 给elementData数组做初始化的工作,并且设置空间长度为10。
	 */
	public ArrayList() {
		this(10);
	}
	/**
	 * 有参构造方法
	 * 给elementData数组做初始化的工作,并且设置指定的空间长度
	 * @param initialCapacity 数组的空间长度数值
	 */
	public ArrayList(int initialCapacity) {
		if(initialCapacity < 0) { // 不合法
			throw new RuntimeException("数组的空间长度不能为负数!" + initialCapacity);
		}
		else {
			// 给elementData数组做初始化的工作,并且设置空间长度为initialCapacity
			this.elementData = new int[initialCapacity];
		}
	}
	/**
	 * 给容器添加数据
	 * @param element 添加的数据
	 */
	public void add(int element) {
		// 1.判断数组是否扩容
		ensureCapacityInternal(size + 5);
		// 2.在数组末尾(size位置的地方)添加新的元素
		elementData[size] = element;
		// 3.实际存放元素个数递增
		size++;
	}
	/**
	 * 根据索引获取数组中的元素
	 * @param index 索引值
	 * @return 返回index索引对应的数组元素
	 */
	public int get(int index) {
		// 1.检查索引是否合法(明确:索引只需要获取实际存入的元素,默认值元素不需要!)
		rangeCheck(index);
		// 2.返回index索引对应数组中的元素
		return elementData[index];
	}
	/**
	 * 在指定索引位置插入元素
	 * @param index 索引值
	 * @param element 需要插入的元素
	 */
	public void add(int index, int element) {
		// 1.检查索引index是否合法(插入的元素可以在实际添加元素的末尾)
		// elementData = {11, 22, 33, 0, 0};
		if(index < 0 || index > size) { 
			System.out.println("索引越界异常!");
			throw new IndexOutOfBoundsException("索引越界异常:" + index);
		}
		// 2.判断数组是否扩容
		ensureCapacityInternal(size + 5);
		// 3.把index之后的元素往后挪动一位(从后往前挪) 
		for(int i = size - 1; i >= index; i--) {
			elementData[i + 1] = elementData[i];	 
		}
		// 4.把元素(element)插入到数组中的index位置
		elementData[index] = element;
		// 5.实际存放元素个数递增
		size++;
	}
	/**
	 * 根据索引删除元素
	 * @param index 索引值
	 * @return 返回被删除的元素
	 */
	public int remove(int index) {
		// 1.检查索引index是否合法 
		rangeCheck(index);
		// 2.获取index对应的被删除元素值
		int oldValue = elementData[index];
		// 3.把删除元素索引(index)之后的元素往前挪动一位(从前往后挪)
		// elementData = {11, 22, 33, 44, 0};
		for(int i = index; i < size - 1; i++) {
			elementData[i] = elementData[i + 1];
		}
		// 4.设置最后一个元素为默认值
		elementData[size - 1] = 0;
		// 5.实际存放元素个数递减
		size--;
		// 6.返回被删除的元素值
		return oldValue;
	}
	/**
	 * 检查索引是否合法,合法索引区间:[0, size-1]
	 * @param index
	 */
	private void rangeCheck(int index) {
		// elementData = {11, 22, 33, 0, 0};
		if(index < 0 || index >= size) {
			throw new IndexOutOfBoundsException("索引越界异常:" + index);
		}
	}
	
	/**
	 * 实现给数组扩容操作
	 * @param capacity 扩容之后数组的空间长度
	 */
	private void ensureCapacityInternal(int capacity) {
		// 1.1当数组实际存放元素的个数和数组的空间长度相等时,这时需要扩容
		if (size == elementData.length) {
			// 1.2创建一个空间长度更大的数组
			int[] newArr = new int[capacity];
			// 1.3把原数组(elementData)中的元素拷贝到新数组newArr中
			System.arraycopy(elementData, 0, newArr, 0, size);
			// 1.4让原数组(elementData)指向新创建出来的数组(newArr)
			elementData = newArr;
		}
	}
}

你可能感兴趣的:(Java,心得,笔记)