理解java容器底层原理--手动实现ArrayList

为了照顾初学者,我分几分版本发出来

版本一:基础版本

 实现对象创建、元素添加、重新toString() 方法

package com.xzlf.collection;

/**
 * 自定义一个ArrayList,体会底层实现原理
 * 初始版本
 * @author xzlf
 *
 * @param <E>
 */
public class MyArrayList<E> {
	private Object[] elementDate;
	private int size;
	private static final int DEFAULT_CAPACITY = 10;
	
	public MyArrayList() {
		elementDate = new Object[DEFAULT_CAPACITY];
	}
	
	public MyArrayList(int capacity) {
		elementDate = new Object[capacity];
	}
	
	public void add(E element) {
		elementDate[size++] = element;
	}
	
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		for (int i = 0; i < size; i++) {
			sb.append(elementDate[i] + ",");
		}
		sb.setCharAt(sb.length() - 1, ']');
		return sb.toString();
	}
	
	public static void main(String[] args) {
		MyArrayList<String> list = new MyArrayList<String>(20);
		list.add("aa");
		list.add("bb");
		list.add("cc");
		System.out.println(list);
	}
}

 

测试运行

版本二:增加扩容

package com.xzlf.collection;

/**
 * 自定义一个ArrayList,体会底层实现原理
 * 增加扩容
 * @author xzlf
 *
 * @param <E>
 */
public class MyArrayList2<E> {
	private Object[] elementDate;
	private int size;
	private static final int DEFAULT_CAPACITY = 10;
	
	public MyArrayList2() {
		elementDate = new Object[DEFAULT_CAPACITY];
	}
	
	public MyArrayList2(int capacity) {
		elementDate = new Object[capacity];
	}
	
	public void add(E element) {
		// 元素个数等于数组长度时 进行扩容操作
		if(size == elementDate.length) {
			Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
			elementDate = newArray;
		}
		elementDate[size++] = element;
	}
	
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		for (int i = 0; i < size; i++) {
			sb.append(elementDate[i] + ",");
		}
		sb.setCharAt(sb.length() - 1, ']');
		return sb.toString();
	}
	
	public static void main(String[] args) {
		MyArrayList2<String> list = new MyArrayList2<String>();
		for (int i = 0; i < 15; i++) {
			list.add("aa" + i);
		}
		System.out.println(list);
	}
}

测试:

版本三:添加get set方法以及数组边界检查

package com.xzlf.collection;

/**
 * 增加get set 方法
 * 增加数组边界检查
 * @author xzlf
 *
 * @param <E>
 */
public class MyArrayList3<E> {
	private Object[] elementDate;
	private int size;
	private static final int DEFAULT_CAPACITY = 10;
	
	public MyArrayList3() {
		elementDate = new Object[DEFAULT_CAPACITY];
	}
	
	public MyArrayList3(int capacity) {
		if(capacity < 0) {
			throw new RuntimeException("数组容量不能为负数");
		}else if(capacity == 0) {
			elementDate = new Object[DEFAULT_CAPACITY];
		}
		elementDate = new Object[capacity];
	}
	
	public void add(E element) {
		// 元素个数等于数组长度时 进行扩容操作
		if(size == elementDate.length) {
			Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
			elementDate = newArray;
		}
		elementDate[size++] = element;
	}
	
	
	public E get(int index) {
		checkRange(index);
		return (E) elementDate[index];
	}
	
	public void set(E element, int index) {
		checkRange(index);
		elementDate[index] = element;
	}
	
	public void checkRange(int index) {
		// 索引合法判断[0,size)
		if(index < 0 || index > size -1) {
			throw new RuntimeException("索引不合法:" + index);
		}
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		for (int i = 0; i < size; i++) {
			sb.append(elementDate[i] + ",");
		}
		sb.setCharAt(sb.length() - 1, ']');
		return sb.toString();
	}
	
	public static void main(String[] args) {
		MyArrayList3<String> list = new MyArrayList3<String>();
		for (int i = 0; i < 15; i++) {
			list.add("aa" + i);
		}
		System.out.println(list);
		System.out.println(list.get(10));
		list.set("bb", 10);
		System.out.println(list.get(10));
		System.out.println(list.get(-10));
	}
}

测试:

版本四:增加remove、size、isEmpty

package com.xzlf.collection;

/**
 * 增加remove()
 * 增加size isEmpty
 * @author xzlf
 *
 * @param <E>
 */
public class MyArrayList4<E> {
	private Object[] elementDate;
	private int size;
	private static final int DEFAULT_CAPACITY = 10;
	
	public MyArrayList4() {
		elementDate = new Object[DEFAULT_CAPACITY];
	}
	
	public MyArrayList4(int capacity) {
		if(capacity < 0) {
			throw new RuntimeException("数组容量不能为负数");
		}else if(capacity == 0) {
			elementDate = new Object[DEFAULT_CAPACITY];
		}
		elementDate = new Object[capacity];
	}
	
	public void add(E element) {
		// 元素个数等于数组长度时 进行扩容操作
		if(size == elementDate.length) {
			Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
			elementDate = newArray;
		}
		elementDate[size++] = element;
	}
	
	
	public E get(int index) {
		checkRange(index);
		return (E) elementDate[index];
	}
	
	public void set(E element, int index) {
		checkRange(index);
		elementDate[index] = element;
	}
	
	public void checkRange(int index) {
		// 索引合法判断[0,size)
		if(index < 0 || index > size -1) {
			throw new RuntimeException("索引不合法:" + index);
		}
	}
	
	public void remove(int index) {
		int numMoved = size - index -1;
		if(numMoved > 0) {
			System.arraycopy(elementDate, index+1, elementDate, index, numMoved);
		}
		elementDate[--size] = null;
	}
	
	public void remove(E element) {
		// 遍历所有元素,和传入的element比较,获取第一个为true的位置 删除
		for (int i = 0; i < size; i++) {
			if(element.equals(get(i))) {
				remove(i);
			}
		}
	}
	
	public int size() {
		return size;
	}
	
	public boolean isEmpty() {
		return size == 0;
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		for (int i = 0; i < size; i++) {
			sb.append(elementDate[i] + ",");
		}
		sb.setCharAt(sb.length() - 1, ']');
		return sb.toString();
	}
	
	public static void main(String[] args) {
		MyArrayList4<String> list = new MyArrayList4<String>();
		for (int i = 0; i < 15; i++) {
			list.add("aa" + i);
		}
		System.out.println(list);
		list.remove("aa7");
		System.out.println(list);
		list.remove(3);
		System.out.println(list);
		System.out.println(list.size());
		System.out.println(list.isEmpty());
	}
}

测试:

posted @ 2020-03-22 18:20  行者老夫  阅读(191)  评论(0编辑  收藏  举报