用数组编写一个ArrayList类

粗略的用数组来实现了ArrayList的方法,不够完善之处继续改正~~
以下是代码:

先定义一个自定义的异常类,用于抛出异常

/**
 * 自定义的MyArrayList的异常类,用于提示MyArrayList操作中的各种异常
 * @author Z-HaiSome
 */
public class MyArrayList_Exception extends Exception{

        public MyArrayList_Exception(){

        }

        public MyArrayList_Exception(String message){
            super(message);
        }
}

再定义一个主类:

/**
 *用数组写一个类似于ArrayList的类
 * @author Z-HaiSome
 */
import java.util.*;

public class MyArrayList{

    //定义初始数组长度defaultLength,值为10,有方法可以修改
    private int defaultLength = 10;

    //定义一个空数组MyList
    private Object[] myList = null;

    /*
         *定义一个数组剩余可用长度,方便添加数据时使用
     *如Object数组o长度为5,只有o[3]、[4]没有有效值,则overPlus为2 
     */
    private int overPlus = 0;

        /**
         * 创建一个默认长度的空列表
         */
    public MyArrayList(){
        myList = new Object[defaultLength];
        overPlus = defaultLength;
    }


        /**
         * 构造一个包含指定 collection 的元素的对象
         * @param c 需要包含的collection接口实现类对象 
         */
    public MyArrayList(Collection c){
        Object[] cTemp = c.toArray();
        int lengthTemp = cTemp.length;
        myList = Arrays.copyOf(cTemp, lengthTemp+defaultLength);
        overPlus = defaultLength;
    }

        /**
         * 构造一个具有指定初始容量的空列表
         * 长度小于或等于0时抛出异常
         * @param length 指定的初始长度
         * @throws MyArrayList_Exception 
         */
    public MyArrayList(int length) throws MyArrayList_Exception{
        if(length<=0){
            throw new MyArrayList_Exception("Function error:MyArrayList(int length).0");
        }else{
            myList = new Object[length];
        }
        overPlus = length;
    }

        /**
         * 更改默认创建数组长度
         * 长度小于1时抛出异常
         * @param length 需要更改的目标长度值
         * @throws MyArrayList_Exception 
         */
    public void changeLength(int length) throws MyArrayList_Exception{
        if(length<=0){
            throw new MyArrayList_Exception("Function error:changeLength(int length).0");
        }else{
            this.defaultLength = length;
        }
    }

        /**
         * 添加元素
         * @param addE 需要添加的元素
         * @return 是否添加成功,true为添加成功,false为添加失败
         * @throws MyArrayList_Exception 
         */
    public boolean add(Object addE)throws MyArrayList_Exception{
        boolean rtn = false;
        int length = myList.length;
        if(overPlus > 0){
            //还有剩余空间时添加元素
            myList[length - overPlus] = addE;
            overPlus = overPlus-1;
            rtn = true;
        }else if(overPlus == 0){
            //没有剩余空间则创建新数组,长度为原来数组的1.33倍
            int addLength = (length/3)>0?(length/3):1;     //防止除以3后为0,最小为1
            Object[] listTemp = Arrays.copyOf(myList, length+addLength);
            myList = listTemp;
            listTemp = null;
            overPlus = addLength;
            //递归回去
            add(addE);
        }else{
            throw new MyArrayList_Exception("Function error:add(Object addE).0");
        }
        return rtn;
    }

        /**
         * 添加元素到指定位置
         * 隔空添加元素将抛出异常
         * @param index 需要添加元素的索引位置
         * @param addE 需要添加的元素
         * @return 是否添加成功,true为添加成功,false为添加失败
         * @throws MyArrayList_Exception 
         */
    public boolean add(int index, Object addE) throws MyArrayList_Exception{
        boolean rtn = false;
        int length = myList.length;
        if(index>length-overPlus){
            //隔空添加元素抛出异常
            throw new MyArrayList_Exception("不能隔空添加元素!");
        }else if(index == length-overPlus){
            //恰好在最后一个有效元素后添加
            add(addE);
            rtn = true;
        }else{
            //在有效元素中间添加元素
            Object[] arrayTemp = new Object[length+1];

            //利用arraycopy方法分两次复制数组
            System.arraycopy(myList,0, arrayTemp,0, index+1);
            System.arraycopy(myList,index+1, arrayTemp,index+2, length-index-1);
            arrayTemp[index] = addE;

            myList = arrayTemp;
            arrayTemp = null;

            //剩余空位没有变,overPlus不用更改
            rtn = true;
        }
        return rtn;
    }

        /**
         * 清除所有元素
         * @return 是否清除成功,true表示清除成功,false表示清除失败
         */
    public boolean clearAll(){
        boolean rtn = false;

        int length = myList.length;
        myList = new Object[length];
        overPlus = length;

        return true;
    }

        /**
         * 检查是否包含指定元素
         * @param o 需要查找的元素
         * @return 有则返回第一处的下标,无则返回-1
         */
    public int contains(Object o){
        int rtn;

        //用转为字符串来检查是否有该元素,这样应该比遍历快吧
        String temp = Arrays.toString(myList);
        if(temp.indexOf(o.toString())==-1){
            //如果不存在该元素则返回-1
            rtn = -1;
        }else{
            for(rtn=0; rtn<myList.length-overPlus; rtn++){
                if(myList[rtn].equals(o)){   //这里应该用equals,试过==,0.9会出错
                    break;
                }
            }
        }
        return rtn;
    }

        /**
         * 返回列表的有效大小
         * @return 列表的有效大小
         */
    public int size(){
        int vaildLength = myList.length - overPlus;
        return vaildLength;
    }

        /**
         * 返回元素数组
         * @return 将列表按照数组返回,数组的类型为Object[]
         */
    public Object[] toArray(){
        int length = myList.length;
        Object[] arrayTemp = Arrays.copyOf(myList, length-overPlus);
        return arrayTemp;
    }

        /**
         * 按照下标返回元素
         * @param index 需要返回元素的索引
         * @return 该索引处的元素
         * @throws MyArrayList_Exception 
         */
    public Object get(int index) throws MyArrayList_Exception{
        Object rtn = null;
        //最大vaildIndex有效的下标
        int vaildIndex = myList.length -overPlus -1;


        if(index<0){
            throw new MyArrayList_Exception("Function error:get(int index):0");
        }else if(index>vaildIndex){
            throw new MyArrayList_Exception("Function error:get(int index):1");
        }else{
            rtn = myList[index];
        }

        return rtn;
    }

        /**
         * 移除元素
         * @param index 需要移除的元素索引
         * @return 是否移除成功,true表示移除成功,false表示移除失败
         * @throws MyArrayList_Exception 
         */
    public boolean remove(int index) throws MyArrayList_Exception{
        boolean rtn = false;
        //最大vaildIndex有效的下标
        int vaildIndex = myList.length -overPlus -1;

        if(index < 0){
            throw new MyArrayList_Exception("Function error:remove.0");
        }else if(index > vaildIndex){
            //超出有效长度
            throw new MyArrayList_Exception("Function error:remove.1");
        }else{
            Object[] arrayTemp = new Object[myList.length -1];
            System.arraycopy(myList,0, arrayTemp,0, index);
            System.arraycopy(myList,index+1, arrayTemp,index, myList.length-index-1);

            myList = arrayTemp;
            arrayTemp = null;
        }

        return rtn;
    }

}

测试类用来测试,

import java.util.*;
public class Test{
    public static void main(String[] args) throws MyArrayList_Exception{
        MyArrayList myl = new MyArrayList();
        System.out.println("myl的长度为:"+myl.size());
        System.out.println("***************************");


        myl.add("text1");
        myl.add(111);
        myl.add(0.9);
        myl.add("text2");
        myl.add("text3");
        myl.add(222);
        myl.add(4444);
        myl.add(666);
        System.out.println("添加8个元素后,myl的长度为:"+myl.size());
        System.out.println("***************************");


        myl.add("元素9");
        myl.add("元素10");
        myl.add("元素11");
        System.out.println("添加多3个元素后,看看超出默认长度可不可以,myl的长度为:"+myl.size());
        for(int i=0;i<myl.size();i++){
            System.out.println("myl["+i+"]="+myl.get(i));
        }
        System.out.println("***************************");


        myl.remove(1);
        myl.remove(6);
        myl.remove(2);
        System.out.println("删除下标为1.6.2三个元素后,myl的长度为:"+myl.size());
        for(int i=0;i<myl.size();i++){
            System.out.println("myl["+i+"]="+myl.get(i));
        }
        System.out.println("***************************");


        Object temp = myl.get(0);
        System.out.println("获得myl[0]:"+temp);
        System.out.println("***************************");


        int co;
        co = myl.contains(2222);
        System.out.println("不存在2222,返回-1:  "+co);
        co = myl.contains("text1");
        System.out.println("存在text1,返回下标0:  "+co);
        co = myl.contains(0.9);
        System.out.println("存在0.9,返回下标1:  "+co);
        System.out.println("***************************");

        myl.clearAll();
        System.out.println("清除所有元素后,列表长度为:"+myl.size());
        System.out.println("***************************");
    }
}

得到结果:
这里写图片描述

测试的时候这几个类应该放到同一个文件夹里面~

猜你喜欢

转载自blog.csdn.net/z_haisome/article/details/52301490
今日推荐