• 自定义实现的ArrayList以及自定义实现的Iterator迭代器


        ArrayList的底层是长度可动态变化的数组,其适用于查找多,修改少的情况,原因是数组的元素的增加删除元素会涉及大量元素的移动,效率比较低,ArrayList中的元素可以重复,与插入时的顺序相同,可以为null,继承自AbstractList,对Collection接口中的部分方法做了实现,实现了List接口,List接口中的方法都需要在ArrayList中进行实现,实现了RandomAccess、Cloneable、java.io.Serializable可以实现克隆,可以实现序列化、反序列化。

    首先创建一个类,创建一个数组和size属性。

    private Object[] elementData;
    private int size;
    
        public MyArrayLIst(){
            this(5);
        }
        //初始化
        public MyArrayLIst(int size) {
            this.elementData = new Object[size];
            this.size = 0;
        }

    获取ArrayList的元素个数:

    /**
         * 获取元素个数
         */
        public int size() {
            return size;
        }

    添加元素:涉及到当前的数组是否满需要扩容的情况,即满则扩容

    /**
         * 添加元素
         */
        public boolean add(T value) {
            //满则扩容
            if (size == elementData.length) {
                elementData = Arrays.copyOf(elementData, elementData.length * 2);
            }
            elementData[size] = value;
            size++;
            return true;
        }

    通过下标获取某个元素:应该判断其参数的合法性

    /**
         * 获取元素
         */
        public T get(int index) {
            T data = (T) new Object();
            if (index >= size || index < 0) {
                throw new RuntimeException("参数不合法");
            } else {
                data = (T) elementData[index];
            }
            return data;
        }

    删除元素:删除元素涉及到元素的移动,便需要将删除元素的后面所有元素向前移动

    /**
         * 删除元素
         */
        public boolean remove(int index) {
            if (index >= size || index < 0) {
                throw new RuntimeException("参数不合法");
            } else {
                for (int i = index; i < size; i++) {
                    //元素的移动
                    elementData[i] = elementData[i + 1];
                }
                elementData[size - 1] = null;//便于GC的回收
                size--;
            }
    
            return true;
        }

    要实现Iterator的接口,便需要自定义的ArrayList实现Iterable接口 ,重写他的Iterator方法,实现一个内部类并且重写Iterator的接口,其中包含三个主要的方法

    boolean  hasNext()

    判断 iterator 内是否存在下1个元素,如果存在,返回true,否则返回false。

    Object next()

    返回 iterator 内下1个元素,同时上面的指针向后移动一位。
    故,如果不断地循环执行next()方法,就可以遍历容器内所有的元素了。

    void remove()

    删除 iterator 内指针的前1个元素,前提是至少执行过1次next();
    (这个方法不建议使用,建议使用容器本身的romove 方法)。

     @Override
        public Iterator<T> iterator() {
            return new str();
        }

    由于其返回的是一个对象,便需要创建一个内部类,来实现其中的方法,代码如下:

     class str implements Iterator<T>{
            int i;
            public str(){
                i = 0;
            }
            @Override
            public boolean hasNext() {
    
                return i++ < size;
            }
    
            @Override
            public T next() {
                if(false){
                }
                return (T)elementData[i-1];
            }
    
            @Override
            public void remove() {
    
            }
        }

    代码改进:

    class str implements Iterator<T>{
        private int nextIndex;
        private int index;
        public str(){
            nextIndex = 0;
            index = -1;      //如果初始数组为空  就不用判断一号位置是否有元素
        }
        @Override
        public boolean hasNext() {
            return nextIndex < size;
        }
    
        @Override
        public T next() {
            int i = nextIndex;
            T value = (T)elementData[i];
            nextIndex++;
            index = i;
           return value ;
    
        }
    
        @Override
        public void remove() {
            MyArrayLIst.this.remove(index);
            nextIndex = index;
            index = -1;
        }
    }

    具体的完整代码如下:

    import java.util.Arrays;
    import java.util.Iterator;
    
    
    
    public class MyArrayLIst<T> implements Iterable<T>{
        private Object[] elementData;
        private int size;
    
        public MyArrayLIst(){
            this(5);
        }
        //初始化
        public MyArrayLIst(int size) {
            this.elementData = new Object[size];
            this.size = 0;
        }
    
        /**
         * 添加元素
         */
        public boolean add(T value) {
            //满则扩容
            if (size == elementData.length) {
                elementData = Arrays.copyOf(elementData, elementData.length * 2);
            }
            elementData[size] = value;
            size++;
            return true;
        }
    
        /**
         * 获取元素
         */
        public T get(int index) {
            T data = (T) new Object();
            if (index >= size || index < 0) {
                throw new RuntimeException("参数不合法");
            } else {
                data = (T) elementData[index];
            }
            return data;
        }
    
        /**
         * 获取元素个数
         */
        public int size() {
            return size;
        }
    
        /**
         * 删除元素
         */
        public boolean remove(int index) {
            if (index >= size || index < 0) {
                throw new RuntimeException("参数不合法");
            } else {
                for (int i = index; i < size; i++) {
                    //元素的移动
                    elementData[i] = elementData[i + 1];
                }
                elementData[size - 1] = null;//便于GC的回收
                size--;
            }
    
            return true;
        }
    
        @Override
        public Iterator<T> iterator() {
            return new str();
        }
    
    //    class str implements Iterator<T>{
    //        int i;
    //        public str(){
    //            i = 0;
    //        }
    //        @Override
    //        public boolean hasNext() {
    //
    //            return i++ < size;
    //        }
    //
    //        @Override
    //        public T next() {
    //            if(false){
    //            }
    //            return (T)elementData[i-1];
    //        }
    //
    //        @Override
    //        public void remove() {
    //
    //        }
    //    }
    class str implements Iterator<T>{
        private int nextIndex;
        private int index;
        public str(){
            nextIndex = 0;
            index = -1;      //如果初始数组为空  就不用判断一号位置是否有元素
        }
        @Override
        public boolean hasNext() {
            return nextIndex < size;
        }
    
        @Override
        public T next() {
            int i = nextIndex;
            T value = (T)elementData[i];
            nextIndex++;
            index = i;
           return value ;
    
        }
    
        @Override
        public void remove() {
            MyArrayLIst.this.remove(index);
            nextIndex = index;
            index = -1;
        }
    }
    
    
        public static void main(String[] args) {
            MyArrayLIst<Integer> myArrayLIst = new MyArrayLIst<>();
            myArrayLIst.add(9);
            myArrayLIst.add(8);
            myArrayLIst.add(1);
            myArrayLIst.add(2);
            myArrayLIst.add(3);
            myArrayLIst.add(5);
         
            System.out.println(myArrayLIst.size());
            System.out.println(myArrayLIst.get(4));
    
    //        myArrayLIst.remove(1);
    //        System.out.println(myArrayLIst.get(1));
            Iterator iterator = myArrayLIst.iterator();
            while (iterator.hasNext()) {
                System.out.print(iterator.next() + " ");
            }
        }
    }

    测试如图:

     

    补充:

    一个迭代器实例只能使用一次,如果要再次使用迭代器,便要创建一个新的迭代器实例。

    
    
  • 相关阅读:
    Algs4-1.3.44文本编辑器的缓冲区
    Algs4-1.3.42复制栈
    Algs4-1.3.41复制队列采用for方式实现
    Algs4-1.3.39环形缓冲区
    Algs4-1.3.40前移编码
    Algs4-1.3.38删除第k个元素-数组实现
    安全测试的一些漏洞和测试方法
    Java内存自动回收,为什么会有内存泄露?
    三款主流静态源代码安全检测工具比较
    Fortify源码安全检测工具
  • 原文地址:https://www.cnblogs.com/128-cdy/p/12029302.html
Copyright © 2020-2023  润新知