zoukankan      html  css  js  c++  java
  • 模仿ArrayList和它的Iterator

    package cn.yangwanhao.collection.list;
    
    import java.util.Iterator;
    import java.util.NoSuchElementException;
    
    /**
     * Title: MyArrayList类<br>
     * Description: 模仿ArrayList和Iterator
     * Company: 卓瀛工作室
     *
     * @author 杨万浩
     * @version 1.0
     */
    public class MyArrayList<E> implements Iterable<E> {
    
        /**
         * 初始化数组容量为10
         */
        private static  final int DEFAULT_CAPACITY = 10;
    
        /**
         * 集合的长度
         */
        private int theSize;
    
        /**
         * 集合体
         */
        private E [] theItems;
    
        /**
         * 构造方法,初始化数组
         */
        public MyArrayList() {
            doClear();
        }
    
        /**
         * 对外提供的初始化数组的方法
         */
        public void clear() {
            doClear();
        }
    
        /**
         * 初始化数组的方法
         */
        private void doClear() {
            //把数组大小设为0
            theSize = 0;
            ensureCapacity(DEFAULT_CAPACITY);
        }
    
        /**
         * 提供集合大小的方法
         * @return 数组的大小
         */
        public int size() {
            return theSize;
        }
    
        /**
         * 判断集合是否为空
         * @return 数组的大小是否为0
         */
        public boolean isEmpty() {
            return theSize==0;
        }
    
        /**
         * 把数组多余的部分切掉
         */
        public void trimToSize() {
            ensureCapacity(size());
        }
    
        /**
         * 数组扩容
         * @param newCapacity 新的数组大小
         */
        private void ensureCapacity(int newCapacity) {
            //如果新的容量比现有的容量还小,直接返回
            if(newCapacity < theSize) {
                System.out.println(newCapacity + " < " + theSize);
                return;
            }
            //获取旧的数组体
            E [] old = theItems;
            //新建一个数组
            theItems = (E []) new Object[newCapacity];
            //把旧的数组copy过去
            for(int i=0; i<size(); i++) {
                theItems[i] = old[i];
            }
        }
    
        /**
         * 获取集合中特定位置的值
         * @param idx 值在集合中的位置
         * @return 该位置的元素
         */
        public E get(int idx) {
            if (idx < 0 || idx >= size()) {
                throw new ArrayIndexOutOfBoundsException();
            }
            return theItems[idx];
        }
    
        /**
         * 修改集合中某个特定位置的元素
         * @param idx 要修改的元素在集合中的位置
         * @param newVal 要修改的元素的新值
         * @return 返回旧的元素(被替换掉的元素)的值
         */
        public E set(int idx, E newVal) {
            if(idx < 0 || idx >= size()) {
                throw new ArrayIndexOutOfBoundsException();
            }
            E old = theItems[idx];
            theItems[idx] = newVal;
            return old;
        }
    
        /**
         * 添加一个元素到集合尾部
         * @param val 要添加的元素
         * @return 添加成功
         */
        public boolean add(E val) {
            add(size(), val);
            return true;
        }
    
        /**
         * 添加元素到指定位置
         * @param idx 位置
         * @param val 元素的值
         */
        public void add(int idx ,E val) {
            //如果数组的容量已经满了,就进行扩容
            if(theItems.length == size()) {
                ensureCapacity(size()+(size()>>1));
            }
            //把idx位置后边的值依次往后挪一位,腾出idx那个位置
            for(int i=theSize; i>idx; i--) {
                theItems[i] = theItems[i-1];
            }
            //赋值
            theItems[idx] = val;
            //集合长度+1
            theSize++;
        }
    
        /**
         * 删除集合中特定位置的一个元素
         * @param idx 位置
         * @return 删除的那个元素
         */
        public E remove(int idx) {
            //得到那个要被删除的元素
            E removeItem = theItems[idx];
            //把该位置元素之后的元素依次向前挪一位
            for (int i=idx; i<size()-1; i++) {
                theItems[i] = theItems[i+1];
            }
            //集合长度-1
            theSize--;
            return removeItem;
        }
    
        /**
         * Returns an iterator over elements of type {@code T}.
         * @return an Iterator.
         */
        @Override
        public Iterator<E> iterator() {
            return new MyArrayListIterator();
        }
    
        private class MyArrayListIterator implements Iterator<E> {
    
            private int current = 0;
    
            @Override
            public boolean hasNext() {
                return current<size();
            }
    
            @Override
            public E next() {
                if(!hasNext()) {
                    throw new NoSuchElementException();
                }
                return theItems[current++];
            }
    
            @Override
            public void remove() {
                MyArrayList.this.remove(--current);
            }
        }
    }

    ArrayList底层使用数组完成。创建时初始化一个数组长度。每次执行添加操作时先查询数组里是否还有空间,如果有就添加,如果没有,则进行扩容操作。扩容就是先获取旧的数组,再创建一个新的数组,初始化它的长度为原数组的1.5倍,再把旧数组的内容拷贝过去。由于每次(在表前或者中间)添加或者删除一个元素都需要挪动后边的元素,所以ArrayList的添加或者删除的效率很低。但是数组根据下标来查询或者修改某个特定的元素时时间复杂度为O(1),所以它的查询很快。至于遍历......他们都是从前往后一个一个遍历,和LinkedList倒是相差无几。

  • 相关阅读:
    使用事务和SqlBulkCopy导入大批量数据
    Windows Server中禁止Administrator用户登录远程桌面
    SQL和C#的常用时间日期处理
    转:SQL Server数据库查询速度慢的原因
    火把节之夜,想发飙
    判断一个字符串是否为空
    .net中的using批注
    [转帖]删除鼠标右键的“用阿里旺旺打开此文件”的命令
    近凌晨12点却毫无睡意
    SQL SERVER取得汉字的拼音缩写
  • 原文地址:https://www.cnblogs.com/yangwanhao/p/10675800.html
Copyright © 2011-2022 走看看