JAVA随时笔记(三):自己实现一个简单的ArrayList

        本着更加深刻的理解ArrayList的目的,所以自己实现一个简单的ArrayList,只是实现了List接口,实现了大部分的方法,其实还有一些地方不完善,比如对于参数的异常判断,返回值的判断,还有常数的直接使用。其实只要明白其中的原理即可。

MyArrayList类:

package testpackge.util;

import java.util.*;

/**
 * 自己实现ArrayList有,实现List接口,实现大部分方法
 *
 * @Authoc: Alic(1071631279 @ qq.com)
 * @creattime: 2018/5/420:11
 */
public class MyArrayList<E> implements List<E>{

    /**
     * MArrayList内部实际是一个object数组,初始化默认是一个空的数组
     */
    private Object[] elementData = {};
    /**
     * 集合中数据的个数
     */
    private int size;

    /**
     * 默认空参构造
     */
    public MyArrayList(){

    }

    /**
     *有参构造
     * @param capacity  初始化容量
     */
    public MyArrayList(int capacity){
        this.elementData = new Object[capacity];
    }

    /**
     * 集合作为构造参数
     * @param c 初始化加入的集合
     */
    public MyArrayList(Collection<? extends E> c){
        this.elementData = c.toArray();
        this.size = c.size();
    }


    /**
     * 添加元素,默认添加到末尾
     * @param e  添加的元素
     * @return   返回false
     */
    public boolean add(E e) {
        //扩容方法
        grow(size+1);
        //把元素添加到元素的末尾
        elementData[size++] = e;
        return true;
    }


    /**
     * 在指定位置添加元素
     * @param index   指定索引位置
     * @param element   添加的元素
     */
    public void add(int index, E element) {
        //越界检查
        if(index>size||index<0){
            throw new RuntimeException("ArrayIndexOutOfBoundsException");
        }
        //扩容
        grow(size+1);
        //把elementData的index及后面的size-index个元素复制到elementData的index+1开始的位置上
        System.arraycopy(elementData,index,elementData,index+1,size-index);
        //index赋值element
        elementData[index] = element;
        //size增加
        size++;
    }

    /**
     * 添加一个集合
     * @param c  添加的集合
     * @return   返回false
     */
    public boolean addAll(Collection<? extends E> c) {
        //转换为数组
        Object[] objects = c.toArray();
        //数组长度
        int num = objects.length;
        //扩容操作
        grow(size+num);
        //把objects的0开始的num个元素复制到elementData的size开始的位置上
        System.arraycopy(objects, 0, elementData, size, num);
        //更改size的值
        size += num;
        return true;
    }


    /**
     * 指定位置添加一个集合
     * @param index   指定位置索引
     * @param c       添加的集合
     * @return        返回true
     */
    public boolean addAll(int index, Collection<? extends E> c) {
        //越界检查
        if(index>size||index<0){
            throw new RuntimeException("ArrayIndexOutOfBoundsException");
        }
        //转换为数组
        Object[] objects = c.toArray();
        //数组的长度
        int num = objects.length;
        //扩容
        grow(size+num);

        //把elementData的index开始的size-index个元素复制到elementData的index+num开始的位置上
        System.arraycopy(elementData,index, elementData, index+num, size-index);
        //把objects的0开始的num个元素复制到elementData的index开始的位置上
        System.arraycopy(objects,0, elementData, index, num);
        //更新size的值
        size += num;
        return true;
    }


    /**
     * 扩容方法
     * @param capacity  需要的最小容量值
     */
    private void  grow(int capacity){
        //集合目前的容量
        int oldcapacity = elementData.length;
        //如果集合初始化为添加任何元素,空的数组
        if(oldcapacity==0){
            //默认容量10
            elementData = new Object[10];
        }else {
            //把容量扩大至原来的1.5倍
            while (capacity < oldcapacity) {
                //把elementData的数据复制到capacity大小的新数组中并且返回,
                elementData = Arrays.copyOf(elementData, capacity = oldcapacity + oldcapacity >> 1);
            }
        }
    }


    /**
     * 移除o元素
     * @param o  删除元素
     * @return   找到删除返回true,否则返回false
     */
    public boolean remove(Object o) {

        //获取索引位置
        int indexOf = indexOf(o);
        if(indexOf>=0){
            //删除索引indexOf的元素
            remove(indexOf);
            return true;
        }
        return false;
    }

    /**
     * 删除index的元素
     * @param index  索引位置
     * @return   返回对应元素
     */
    public E remove(int index) {
        //越界检查
        if(index>size||index<0){
            throw new RuntimeException("ArrayIndexOutOfBoundsException");
        }
        E e = (E)elementData[index];
        //把elementData的index+1开始的size-index-1个元素复制到elementData的index开始的位置上
        System.arraycopy(elementData,index+1,elementData,index,size-index-1);
        //把最后一个元素置为null,便于GC,size更新
        elementData[size--] = null;
        return e;
    }

    /**
     * 移除c的全部集合
     * @param c  集合对象
     * @return   返回true
     */
    public boolean removeAll(Collection<?> c) {
        //迭代器迭代删除
        Iterator<?> iterator = c.iterator();
        while(iterator.hasNext()){
            Object next = iterator.next();
            remove(next);
        }
        return true;
    }

    /**
     * 获取o对应的索引
     * @param o   查找的对象
     * @return    返回对应索引位置,找到就返回
     */
    public int indexOf(Object o) {
        //如果是null值,循环遍历判断有无null值
        if(o==null){
            for(int i = 0;i<size;i++){
                if(elementData[i]==null){
                    return i;
                }
            }
        }else{
            //循环遍历判断,使用equals判断是否相等
            for(int i = 0;i<size;i++){
                if(o.equals(elementData[i])){
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 获取集合中最后一个o值
     * @param o  获取o相等的值
     * @return  返回对应的索引位置
     */
    public int lastIndexOf(Object o) {
        //循环从后向前白遍历
        if(o==null){
            for(int i = size-1;i>=0;i--){
                if(elementData[i]==null){
                    return i;
                }
            }
        }else{
            for(int i = size-1;i>=0;i--){
                if(o.equals(elementData[i])){
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 获取size的值
     * @return  返回size值
     */
    public int size() {
        return size;
    }

    /**
     * 判断是否为空,即判断size是否为0
     * @return  为空返回true,否则返回false
     */
    public boolean isEmpty() {
        return size==0;
    }

    /**
     * 判断是否包含o值,如果indexOf返回-1就没有对应的值
     * @param o  判断包含的值
     * @return   包含就返回true,否则返回false
     */
    public boolean contains(Object o) {
        return indexOf(o)>=0;
    }


    /**
     * 是否包含c中所有的值
     * @param c  判断的集合对象
     * @return  全部包含返回true,否则返回false
     */
    public boolean containsAll(Collection<?> c) {

        //迭代判断,有一个不是就返回false
        Iterator<?> iterator = c.iterator();
        while(iterator.hasNext()){
            Object next = iterator.next();
            if(indexOf(next)<0){
                return false;
            }
        }
        return true;
    }


    /**
     * 清除集合元素
     */
    public void clear() {
        //循环遍历置为null.便于GC
        for(int i = size-1;i>=0;i--){
            elementData[i]=null;
        }
        //更改size为0
        size = 0;
    }

    /**
     * 获取index所有上的值
     * @param index
     * @return  返回对应的元素
     */
    public E get(int index) {
        //越界检查
        if(index>size||index<0){
            throw new RuntimeException("ArrayIndexOutOfBoundsException");
        }
        return (E)elementData[index];
    }


    /**
     * 更新index上的值为element
     * @param index
     * @param element
     * @return  返回index旧的值
     */
    public E set(int index, E element) {
        //越界检查
        if(index>size||index<0){
            throw new RuntimeException("ArrayIndexOutOfBoundsException");
        }
        //index的原始值
        E e = (E)elementData[index];
        //更改index的引用为element
        elementData[index] = element;
        return e;
    }

    /**
     * 转换为数组
     * @return   返回数组
     */
    public Object[] toArray() {
        //创建一个长度为size的数组,循环遍历赋值
        Object[] objects = new Object[size];
        for(int i = 0;i<size;i++){
            objects[i]=elementData[i];
        }
        return objects;
    }

    /**
     * 截取formIndex到toIndex的值的集合,包含左右边界
     * @param fromIndex  起始值
     * @param toIndex    结束值
     * @return   返回截取的集合
     */
    public List<E> subList(int fromIndex, int toIndex) {
        //越界检查,已经确保fromIndex小于等于toIndex
        if(fromIndex>size||fromIndex<0||toIndex>size||toIndex<0||fromIndex>toIndex){
            throw new RuntimeException("ArrayIndexOutOfBoundsException");
        }
        //创建新的对象
        MyArrayList<E> myArrayList = new MyArrayList();
        //创建toIndex-fromIndex+1长度的数组
        Object[] objects = new Object[toIndex-fromIndex+1];
        //遍历赋值
        for(int i = fromIndex;i<=toIndex;i++){
            objects[i]=elementData[i];
        }
        //设置size值
        myArrayList.size = toIndex-fromIndex+1;
        //设置集合的元素数组
        myArrayList.elementData = objects;
        return myArrayList;
    }


    /**
     * 重写toString方法
     * @return  返回集合数据的字符串
     */
    @Override
    public String toString() {
        //创建stringBuder对象
        StringBuilder stringBuilder = new StringBuilder();
        //遍历拼接字符串,每一个对象加一个","
        stringBuilder.append("[");
        for(int i = 0;i<size;i++){
            stringBuilder.append(((E)elementData[i]).toString());
            stringBuilder.append(",");
        }

        //清除最后一个","字符
        int lastIndexOf = stringBuilder.lastIndexOf(",");
        if(lastIndexOf>0){
            stringBuilder.deleteCharAt(lastIndexOf);
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    /**
     * 迭代器对象
     */
    public class Itr implements Iterator<E>{
        /**
         * 迭代到的索引位置
         */
        private int cursor;

        /**
         * 是否还有下一个元素,即判断迭代位置是否已到size
         * @return 还有返回true,没有返回false
         */
        @Override
        public boolean hasNext() {
            return cursor!=size;
        }

        /**
         * 返回下一个元素,直接返回elementData的对应数据
         * @return 返回对应元素
         */
        @Override
        public E next() {
            return (E)elementData[cursor++];
        }
    }

    /**
     * 返回迭代器对象,创建一个内部类
     * @return  内部类迭代器对象
     */
    public Iterator<E> iterator() {
        return new Itr();
    }

   //下面的方法其实都是一样的,只要明白了其中的原理即可,以下四个方法不实现了

    public ListIterator<E> listIterator() {
        return null;
    }

    public ListIterator<E> listIterator(int index) {
        return null;
    }

    public boolean retainAll(Collection<?> c) {
        return false;
    }

    public <T> T[] toArray(T[] a) {
        return null;
    }
}

Main测试代码:

 
MyArrayList<ClassA> myArrayList = new MyArrayList();
ClassA a1 = new ClassA(12,"a1");
ClassA a2 = new ClassA(13,"a2");
ClassA a3 = new ClassA(14,"a3");
ClassA a4 = new ClassA(15,"a4");

System.out.println("------初始化后------");
System.out.println("size:"+myArrayList.size());

System.out.println("------开始添加元素------");
myArrayList.add(a1);
System.out.println(myArrayList);

System.out.println("contrins方法,是否包含a1:"+myArrayList.contains(a1));
System.out.println("size:" + myArrayList.size());

System.out.println("在1位置添加一个元素a2");
myArrayList.add(1,a2);
System.out.println(myArrayList);
System.out.println("size:" + myArrayList.size());
System.out.println("在2位置添加一个元素a3");
myArrayList.add(2,a3);
System.out.println(myArrayList);
System.out.println("size:" + myArrayList.size());

System.out.println("获取2位置上的元素:"+myArrayList.get(2));


System.out.println("获取a1元素的索引位置:" + myArrayList.indexOf(a1));

System.out.println("判断集合是否为空:" + myArrayList.isEmpty());

System.out.println("移除索引为1的元素:");
myArrayList.remove(1);
System.out.println(myArrayList);
System.out.println("size:" + myArrayList.size());
System.out.println("移除a3:");
myArrayList.remove(a3);
System.out.println(myArrayList);
System.out.println("size:" + myArrayList.size());

System.out.println("添加a2元素");
myArrayList.add(a2);
System.out.println(myArrayList);
System.out.println("size:" + myArrayList.size());
System.out.println("更新索引1位置的元素为a4");
myArrayList.set(1,a4);
System.out.println(myArrayList);
System.out.println("添加a3元素");
myArrayList.add(a3);
System.out.println(myArrayList);
System.out.println("size:" + myArrayList.size());

System.out.println("截取索引为0-2的元素,得到subList:");
List<ClassA> subList = myArrayList.subList(0, 2);
System.out.println(subList);

System.out.println("clear方法清空subList:");
subList.clear();
System.out.println(subList);

System.out.println("toArray方法得到数组:");
Object[] objects = myArrayList.toArray();
for (int i = 0,len = myArrayList.size();i<len;i++){
    System.out.println(myArrayList.get(i));
}

System.out.println("迭代器测试:");
Iterator<ClassA> iterator = myArrayList.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next());
}

System.out.println("有参构造得到arrayList");
MyArrayList arrayList = new MyArrayList(myArrayList);

System.out.println(arrayList);


输出结果:

------初始化后------
size:0
------开始添加元素------
[ClassA{age=12, name='a1'}]
contrins方法,是否包含a1:true
size:1
在1位置添加一个元素a2
[ClassA{age=12, name='a1'},ClassA{age=13, name='a2'}]
size:2
在2位置添加一个元素a3
[ClassA{age=12, name='a1'},ClassA{age=13, name='a2'},ClassA{age=14, name='a3'}]
size:3
获取2位置上的元素:ClassA{age=14, name='a3'}
获取a1元素的索引位置:0
判断集合是否为空:false
移除索引为1的元素:
[ClassA{age=12, name='a1'},ClassA{age=14, name='a3'}]
size:2
移除a3:
[ClassA{age=12, name='a1'}]
size:1
添加a2元素
[ClassA{age=12, name='a1'},ClassA{age=13, name='a2'}]
size:2
更新索引1位置的元素为a4
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'}]
添加a3元素
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'},ClassA{age=14, name='a3'}]
size:3
截取索引为0-2的元素,得到subList:
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'},ClassA{age=14, name='a3'}]
clear方法清空subList:
[]
toArray方法得到数组:
ClassA{age=12, name='a1'}
ClassA{age=15, name='a4'}
ClassA{age=14, name='a3'}
迭代器测试:
ClassA{age=12, name='a1'}
ClassA{age=15, name='a4'}
ClassA{age=14, name='a3'}
有参构造得到arrayList
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'},ClassA{age=14, name='a3'}]

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值