欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA实现自定义实现的ArrayList

程序员文章站 2022-10-03 16:04:37
那,为了更加深刻理解ArrayList的底层原理实现,就写一个自定义的ArrayList集合,实现出底层的基本功能,关于一些底层的原理,可以参考文章:https://blog.csdn.net/weixin_46726346/article/details/107562529好,言归正传,现在开始写:1、arraycopy的用法最开始想介绍一个方法arraycopy这个方法的使用,因为这个方法会被用到;我们用代码加图解来介绍:int arr[]=new int[5];for(int i...

那,为了更加深刻理解ArrayList的底层原理实现,就写一个自定义的ArrayList集合,实现出底层的基本功能,关于一些底层的原理,可以参考文章:
https://blog.csdn.net/weixin_46726346/article/details/107562529

好,言归正传,现在开始写:

1、arraycopy的用法

最开始想介绍一个方法arraycopy这个方法的使用,因为这个方法会被用到;
我们用代码加图解来介绍:

		int arr[]=new int[5];
		for(int i=0;i<arr.length;i++) {
			arr[i]=i;
		}

写了一个大小为5的数组,值分别为01234对吧;
JAVA实现自定义实现的ArrayList
看图,我现在想把3,4这两个元素去替换前面的1,2这两个元素,看我的操作:

System.arraycopy(arr, 3, arr, 1, 2);

就这一行代码,那是什么意思呢:

public static void arraycopy(Object src, int srcPos, Object dest,int destPos,int length)

从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。

然后数组就变成了:

JAVA实现自定义实现的ArrayList

好,这个方法理解了,我们就开始写这个自定义的ArrayList!

首先肯定要创建好类,然后再给类加个泛型:

public class MyArrayList<E> {}

然后就开始写了

2、成员变量

我们在上一篇中说过,ArrayList底层是一个数组,
那么成员变量 最主要的就是要有一个数组来存储元素

private Object[] elementData;

然后要有记录元素个数的成员变量

private int size;

然后在初始化的时候,要有一个空数组(上一篇说过就不详细说了)

private Object[] emptyArray[]= {};

再有一个第一次扩容的初始容量10,应该定义为常量

private final int capcity=10;

3、构造方法

说完成员变量,第一个方法肯定是构造方法;
我们这里只写一个无参数的构造方法
我们知道在调用无参数构造方法的时候会初始化一个容量为0的数组:

	public MyArrayList() {
		elementData=emptyArray;
	}

这就用到了之前定义的成员变量!

4、扩容方法

关于扩容方法,我们知道,第一次调用add函数的时候,会把容量设置为10;
然后每次添加元素,数组不够了之后,会吧容量扩容至原来的1.5倍:
这里的1.5倍,我们是有移位运算符来写的(底层就是)

	private void grow() {
		if(elementData==emptyArray) {
			elementData=new Object[capcity];
		}
		if(size==elementData.length) {
			int oldCpacity=elementData.length;
			int newCapcity=oldCpacity+(oldCpacity>>1);
			Object obj[]=new Object[newCapcity];
			System.arraycopy(obj, 0, obj, 0, oldCpacity);
			elementData=obj;
		}
		
	}

然后这个方法不被外界调用,所以我们设置成私有的,由于只有在调用add方法的时候,才会调用grow方法,所以我们写一下add方法;

5、add方法

我们知道add方法返回值是布尔类型,并且把元素添加到尾部,size加一;
每次调用add方法都要调用一次grow方法:

	public boolean add(E e) {
		grow();
		elementData[size++]=e;
		return true;
	}

6、toString方法

我们上篇说过,toString方法底层是通过迭代器进行遍历,我们自己写就用随机访问来进行遍历数组,输出字符串,在这里最好不要用+来写,用StringBuilder来写来减少开销:

	public String toString() {
		if(size==0) {
			return "[]";
		}
		
		StringBuilder str=new StringBuilder();
		str.append("[");
		for(int i=0;i<size;i++) {
			if(i==size-1) {
				str.append(elementData[i]).append("]");
			}
			else {
				str.append(elementData[i]).append(",").append(" ");
			}
		}
		
		return str.toString();
	}

7、set方法

set方法,返回值是被修改的元素,我们要判断索引的位置是否有错,如果正常,就可以直接修改元素了!

	public E set(int index,E element) {
		if(index<0||index>size) {
			throw new IndexOutOfBoundsException("索引越界");
		}
		E value =(E) elementData[index];
		elementData[index]=element;
		return value;
	}

8、remove方法

如果我们要删除一个元素,首先要判断位置是否有错误,然后把索引位置的元素删除,后面所有的元素向前一位,哎,这里就用到了arraycopy这个方法:

	public E remove(int index) {
		if(index<0||index>size) {
			throw new IndexOutOfBoundsException("索引越界");
		}
		E value =(E) elementData[index];
		int numMoved=size-index-1;
		if(numMoved>0) {
			System.arraycopy(elementData, index+1, elementData, index, numMoved);
		}
		elementData[--size]=null;
		return value;
	}

就相当于把要删除的元素,后面所有的元素复制到前一个位置上,然后再把最后的一个元素置空;
返回值呢,就是被删除的元素;

9、get方法

获取元素就更简单了,判断索引,正常的话直接返回就好了,返回元素个数也是一样的!

	public E get(int index) {
		if(index<0||index>size) {
			throw new IndexOutOfBoundsException("索引越界");
		}
		return (E) elementData[index];
	}
	public int getSize() {
		return size;
	}

到此基本的方法就全写完了,然后我们在主函数里面测试一下:

10、test函数

	public static void main(String[] args) {
		MyArrayList<String> list=new MyArrayList();
		list.add("123");
		list.add("456");
		list.add("789");
		list.set(1, "abc");
		list.remove(2);
		System.out.println(list.get(0));
		System.out.println(list.getSize());
		System.out.println(list);
	}

然后我们看一下输出:
123
2
[123, abc]

也是木有问题的,好了,到此就结束了,关于ArrayList就这样了!

本文地址:https://blog.csdn.net/weixin_46726346/article/details/107580973