最近准备找工作,就复习了下Java的基础,顺便多看看源码,在复习到集合这一章时,就想着自己动手实现集合,就看了看jdk的源码,由于笔者本科学的是高分子材料,和计算机、软件、互联网完全不沾边,也没学过数据结构,但为了多了解这方便的知识,就根据jdk的源码,模仿了集合的实现,今天给大家带来的是ArrayList的实现,当然在这里笔者也只是实现了集合中部分常用的方法,并且也没有使用泛型。
首先笔者也是自己定义了一个MyList(对应jdk里面的List)接口(笔者没有像jdk里面去定义Collection接口),然后定义了一个MyList的实现类--MyArrayList。
具体代码如下,代码中有相关的注释,读者根据注释去学习:
package com.tiantang.collection;/*** 自定义的List接口* @author LiuJinkun**/
public interface MyList {/*** 增加元素* @param obj*/void add(Object obj);/*** 在指定索引处增加元素* @param index* @param obj*/void add(int index,Object obj);/*** 根据对象删除元素* @param obj*/void remove(Object obj);/*** 根据索引删除元素* @param index*/void remove(int index);/*** 返回指定索引处的元素* @param index* @return*/Object get(int index);/*** 修改指定索引处的元素* @param index* @param obj*/void set(int index,Object obj);/*** 返回元素所在的索引* @param obj* @return*/int indexOf(Object obj);/*** 判断集合是否为空* @return*/boolean isEmpty();/*** 清空集合*/void clear();int size();}
package com.tiantang.collection;/*** 自定义实现ArrayList* @author LiuJinkun**/
public class MyArrayList implements MyList{//ArrayList集合的底层实现是数组,因此定义了一个数组,用来存放元素private Object[] elementData;//数组的大小private int size;public int size(){return size;}/*** 无参构造器,默认初始化数组的大小为10*/public MyArrayList(){this(10);}/*** 有参构造器,根据传入的数字来初始化数组的大小* @param initialCapacity*/public MyArrayList(int initialCapacity){if(initialCapacity>0){elementData=new Object[initialCapacity];}else{throw new IllegalArgumentException();}}@Overridepublic void add(Object obj) {//先判断数组容量是否足够ensureCapacity();elementData[size++]=obj;}private void ensureCapacity() {if(size==elementData.length){//扩容Object[] newArray=new Object[size*2+1];//然后将原数组的数据拷贝到新数组System.arraycopy(elementData, 0, newArray, 0, elementData.length);//最后让原数组的引用指向新数组对象elementData=newArray;}}@Overridepublic void add(int index, Object obj) {//先判断索引是否越界rangCheck(index);ensureCapacity();//再进行数组的拷贝(为索引为index的位置腾出空位)System.arraycopy(elementData, index, elementData, index+1, size-index);//最后添加元素elementData[index]=obj;size++;}private void rangCheck(int index) {if(index<0||index>=size){throw new IllegalArgumentException();}}@Overridepublic void remove(Object obj) {for(int i=0;i<size;i++){if(elementData[i].equals(obj)){remove(i);}}}@Overridepublic void remove(int index) {rangCheck(index);System.arraycopy(elementData, index+1, elementData, index, size-index-1);elementData[size--]=null;}@Overridepublic Object get(int index) {//判断索引是否合法if(index>=size){throw new IllegalArgumentException();}return elementData[index];}@Overridepublic void set(int index, Object obj) {rangCheck(index);elementData[index]=obj;}/*** 返回元素第一次出现在集合中的索引,若集合中不包含该元素就返回-1*/@Overridepublic int indexOf(Object obj) {for(int i=0;i<size;i++){if(elementData[i].equals(obj)){return i;}}//不包含该元素就返回-1return -1;}@Overridepublic boolean isEmpty() {return size==0?true:false;}@Overridepublic void clear() {for(int i=0;i<size;i++){elementData[i]=null;}size=0;}}
上面的代码,经过笔者测试,不存在BUG,当然安全性肯定没有JDK的好,代码的优化也没有JDK做得好,笔者写这些代码,纯属只是为了练习,加深印象。后续笔者还会陆续实现其他的集合。