zoukankan      html  css  js  c++  java
  • 自己实现基于数组的ArrayList的基本api


    写一个自己的ArrayList
    * 集合类 容器
    *
    * 1 里面提供了哪些操作? 参考List接口
    *
    * 2 里面有哪些数据? 成员变量 分析
    *
    * 3 构造方法;

    接口List

    import java.util.Iterator;
    import java.util.ListIterator;
    
    public interface List<E> {
        boolean add(E e);
    
        void add(int index,E e);
    
        void remove(E e);
    
        E remove(int index);
    
        boolean contains(E e);
    
        void clear();
    
        E get(int index);
    
        int indexof(E e);
    
        int lastIndexof(E e);
    
        void set(int index,E e);
    
        int size();
    
        boolean isEmpty();
    
        ListIterator<E> iterator();
    
        ListIterator<E> iterator(int index);
    }
    

    Test

    package javahomework.day29;
    
    import java.util.ListIterator;
    
    public class Test {
        public static void main(String[] args) {
            MyList<String> ms = new MyList<>();
            boolean empty = ms.isEmpty();
            //System.out.println(empty);
            ms.add("a");
            ms.add("b");
            ms.add("d");
            ms.add("e");
            ms.add("a");
            System.out.println(ms.size);
    
            //ms.remove(1);
            System.out.println(ms);
    
            ListIterator listIterator = ms.iterator();
            while(listIterator.hasNext()){
                Object next = listIterator.next();
    
                if("a".equals(next)){
                    ms.remove(next);
                    //listIterator.add("java");
                }
            }
            while(listIterator.hasPrevious()){
                Object previous = listIterator.previous();
    
                if("a".equals(previous)){
                    //listIterator.add("java");
                }
            }
            System.out.println(ms);
        }
    }
    

      

    MyList

    package javahomework.day29;
    
    
    import java.util.Arrays;
    import java.util.ConcurrentModificationException;
    import java.util.ListIterator;
    import java.util.NoSuchElementException;
    
    /*
     * 写一个自己的ArrayList
     */
    public class MyList<E> implements List<E> {
    
        public Object[] element;//存储数据的数组
    
        int size;//数据元素的个数
    
        int modecount;//集合修改的次数
    
        private static final int Defaultcapcity = 10;  //默认分配的容量
        private static final int Max_arry = Integer.MAX_VALUE-8;//最大数组容量
    
        //无参构造,分配默认的容量Defaultcapcity
        public  MyList(){
            element = new Object[Defaultcapcity];
        }
    
        //有参构造,分配指定容量
        public MyList(int capcity) {
            //判断参数是否合法
            if(capcity<0||capcity>Max_arry){
                throw new IllegalArgumentException("非法参数");
            }
            element = new Object[capcity];
        }
    
        /**
         * toString方法 把集合元素输出
         * @return  返回集合元素的字符串
         */
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            if(size>0){
                for(int i =0; i < size-1; i++){
                    sb.append(element[i]+" ");
                }
                sb.append(element[size-1]);
            }
    
            sb.append("]");
            return sb.toString();
        }
    
        /**
         * 在集合末尾增加一个元素
         * @param o  任意指定类型
         * @return  返回true添加成功
         */
        @Override
        public boolean add(Object o) {
    
            add(size,o);
            return true;
        }
    
        /**
         * 在index位置添加元素
         * @param index  集合的索引位置
         * @param o   任意类型数据
         */
        @Override
        public void add(int index, Object o) {
            checkIndex(index);   //检查索引是否合法
    
            int mincapcity = size+1;  //要添加元素,那么最小容量至少为size+1
    
            if(mincapcity>element.length){  //判断最小需要的容量与分配的容量的大小,决定是否需要扩容
    
                int newcapcity = element.length+(element.length<<1);  //新的容量一般为原容量的1.5倍
                if(newcapcity<0||newcapcity>Max_arry){    //如果新的容量不符合容量的要求
                    newcapcity = Max_arry;                //直接把新的容量设为容量最大值
                }
                if(mincapcity>newcapcity){                //计算好新的容量后,比较最小需要的容量和新的容量,二者的较大值才为需要的新的的容量
                    newcapcity= mincapcity;
                }
                Object[] objects = new Object[newcapcity];//用需要的容量创建新的数组
                for(int i=0;i<newcapcity;i++){            //新的数组存入element数组的数据
                    objects[i] = element[i];
                }
                element = objects;                        //element数组指向新数组引用
            }
    
    
    
            for(int i = size; i>index; i--){              //开始添加数据,首先把添加位置后的数据都向后移动
                element[i] = element[i-1];
            }
    
            element[index] = o;                           //在要添加的位置添加数据
            modecount++;                                  //修改集合次数+1
            size++;                                       //集合元素个数+1
        }
    
        /**
         * 检查索引是否合法
         * @param index  索引
         */
        private void checkIndex(int index) {
            if(index<0||index>size){
                throw new IllegalArgumentException("非法参数");
            }
        }
    
        /**
         * 移除指定元素(有重复的移动位置最前的)
         * @param o
         */
        @Override
        public void remove(Object o) {
    
            int index = indexof(o);
            if(index!=-1){      //如果索引可以找到
                remove(index);
            }
        }
    
        /**
         * 移除指定位置的元素
         * @param index 索引
         * @return 返回移除的元素
         */
        @Override
        public E remove(int index) {
            checkIndex(index); //检查索引是否合法
    
            E e = (E) element[index];  //临时保存所移除元素
            for (int i = index; i <size ; i++) {  //移除元素,需要把index之后的 元素向前移动
                element[i] = element[i+1];
            }
            element[size] = null;      //移除后空出位置需要置为空
    
            size--;                    //元素个数-1
            modecount++;               //修改集合次数+1
            return e;
        }
    
        /**
         * 判断集合中是否包含此元素
         * @param e  任意类型数据
         * @return  返回true表示找到,否则返回false
         */
        @Override
        public boolean contains(E e) {
            int i = indexof(e);
            return i!=-1;
        }
    
        /**
         * 清空集合元素
         */
        @Override
        public void clear(){
            for (int i = 0; i < size; i++) {
                element[i] =null;               //所有元素置为空
            }
            size = 0;                           //元素个数置为0
            modecount++;                        //修改集合次数+1
        }
    
        /**
         * 得到集合指定位置的元素
         * @param index  索引
         * @return  返回指定位置的元素
         */
        @Override
        public E get(int index) {
            checkIndex(index);         //判断索引是否合法
            return (E) element[index];
        }
    
        /**
         * 找到指定元素的位置
         * @param o 任意类型
         * @return 找到返回元素位置,否则返回-1
         */
        @Override
        public int indexof(Object o) {
    
            for (int i = 0; i < size; i++) {
                if(element[i].equals(o)){
                    return i;
                }
            }
            return -1;
        }
    
        /**
         * 找到指定元素最后一个的位置
         * @param o 任意类型
         * @return 找到返回元素位置,否则返回-1
         */
        @Override
        public int lastIndexof(Object o) {
    
            for (int i = size-1; i >=0; i--) {  //从后向前找方便
                if(element[i].equals(o)){
                    return i;
                }
            }
            return -1;
        }
    
        /**
         * 修改集合指定位置的元素
         * @param index 索引
         * @param o 任意类型
         */
        @Override
        public void set(int index, Object o) {
            checkIndex(index);    //检查索引合法性
            element[index] = o;
        }
    
        /**
         * 返回集合元素个数
         * @return size
         */
        @Override
        public int size() {
            return size;
        }
    
        /**
         * 判断集合是否为空
         * @return  为空返回true,否则返回false
         */
        @Override
        public boolean isEmpty() {
            return size==0;
        }
    
        /**
         * 迭代器无参构造
         * @return  ListIterator<E>
         */
        @Override
        public ListIterator<E> iterator() {
            return new MyIterator();
        }
    
        /**
         * 迭代器有参构造
         * @param index 索引
         * @return ListIterator<E>
         */
        @Override
        public ListIterator<E> iterator(int index) {
            return new MyIterator(index);
        }
    
        //成员内部类实现迭代器
        public class MyIterator<E> implements ListIterator<E> {
    
            int cursor;  //游标
    
            int lastRet=-1; //记录上一次next或previous返回元素的索引位置
    
            int expectedmodecount = modecount; //记录集合修改次数,用于检查是否出现并发修改
    
            public MyIterator(int cursor) {    //迭代器有参构造
                if(cursor<0||cursor>size){     //游标合法性,对应size
                    throw new IllegalArgumentException("-1");
                }
                this.cursor = cursor;
            }
    
            public MyIterator() {}  //无参构造
    
    
            /**
             * 判断是否有下一个元素
             * @return 有返回true,否则返回false
             */
            @Override
            public boolean hasNext() {
                return cursor<size;  //游标对应size
            }
    
            /**
             *
             * @return  返回游标的下一个元素
             */
            @Override
            public E next() {
    
                checkBinfa();   //并发检查
                if(hasNext()){  //有下一个元素
                    E e = (E) element[cursor];  //保存下一个元素
                    lastRet=cursor;            //记录上一次next或previous返回元素的索引位置
                    cursor++;                  //游标后移
                    return e;
                }else {
                    throw new NoSuchElementException();
                }
    
            }
    
            /**
             * 检查是否发生并发修改
             */
            private void checkBinfa() {
                if(expectedmodecount!=modecount){
                    throw new ConcurrentModificationException();
                }
            }
    
            /**
             * 判断是否有前一个元素
             * @return  有的话返回true,没有返回false
             */
            @Override
            public boolean hasPrevious() {
                return cursor>0;
            }
    
            /**
             *
             * @return  返回游标的上一个元素
             */
            @Override
            public E previous() {
                checkBinfa();   //并发修改检查
                if(hasPrevious()){      //有上一个元素
                    E e = (E) element[cursor-1];  //保存上一个元素
    
                    cursor--;                     //游标前移
                    lastRet = cursor;             //记录上一次next或previous返回元素的索引位置
                    return e;
                }else{
                    throw new NoSuchElementException();
                }
            }
    
            /**
             *
             * @return  返回对 next 的后续调用所返回元素的索引。
             */
            @Override
            public int nextIndex() {
    
                return cursor;
            }
    
            /**
             *
             * @return  返回对 previous 的后续调用所返回元素的索引。
             */
            @Override
            public int previousIndex() {
                return cursor--;
            }
    
            /**
             * 移除next 或者 previous 返回的最后一个位置的元素
             */
            @Override
            public void remove() {
                if(lastRet==-1){      //如果已经修改过,就不再允许在当前游标位置进行修改
                    throw new IllegalStateException();
                }
                checkBinfa();               //并发修改检查
                MyList.this.remove(cursor);  //删掉
                expectedmodecount = modecount;//迭代器的自身的修改不会引发并发修改异常
                cursor = lastRet;              //这里next和previous统一处理即可
                lastRet=-1;                    //不允许在当前游标位置进行修改,如果修改就会发生逻辑错误
            }
    
            /**
             *  修改curcor位置的元素的值
             * @param e
             */
            @Override
            public void set(E e) {
                if(lastRet == -1){    // 如果已经修改过,就不再允许在当前游标位置进行修改
                    throw new IllegalStateException();
                }
                checkBinfa();
                MyList.this.set(cursor,e);
            }
    
            /**
             * 在当前curcor位置添加一个元素
             * @param e
             */
            @Override
            public void add(E e) {
                if(lastRet==-1){       // 如果已经修改过,就不再允许在当前游标位置进行修改
                    throw new IllegalStateException();
                }
                checkBinfa();           //并发修改检查
                MyList.this.add(cursor,e);
                expectedmodecount = modecount;//迭代器的自身的修改不会引发并发修改异常
                cursor++;                     //游标后移
                lastRet = -1;                  //不允许在当前游标位置进行修改,如果修改就会发生逻辑错误
            }
        }
    
    
    }
    

      

  • 相关阅读:
    mysql 加入列,改动列,删除列。
    C语言中的static 具体分析
    [Python网络编程]gevent httpclient以及网页编码
    iOS学习之 plist文件的读写
    数据库设计中的14个技巧
    最简单的基于FFMPEG的封装格式转换器(无编解码)
    一次重要的爱情婚姻抉择,您怎么看?
    2014年到期的myeclipse5.5.1注冊码
    24点经典算法
    使用val()方法设置表单中的默认选中项
  • 原文地址:https://www.cnblogs.com/hfc-xx/p/13509657.html
Copyright © 2011-2022 走看看