美文网首页
手写简单的ArrayList

手写简单的ArrayList

作者: Ethan_zyc | 来源:发表于2019-05-23 08:35 被阅读0次

    注释都在代码里,就是数组集合,实现简单的增删改查,考虑的没有jdk源码详细,欢迎指出bug

    package com.ethanzyc.allinone.dataStructure.List;
    
    /**
     * 手写一个数组集合
     * @author ethan
     * @date 2019/5/17 02:41
     */
    public class MyArrayList<T> {
        /** array list 简单说就是内存地址在硬盘中是连续的数组 **/
        private T[] array;
        /** index相当于数组的指针,通过指针来表示数组的长度,以及定位添加的位置 **/
        private int index;
    
        /**
         * 数组集合无参构造函数,不指定容量就默认为10
         */
        public MyArrayList() {
            this(10);
        }
    
        /**
         * 数组集合指定长度构造函数
         * @param length
         */
        public MyArrayList(int length) {
            this.array = (T[]) new Object[length];
        }
    
        /**
         * 获取数组的长度,有多少值,size就是多少,不同于数组的容量
         * 其实是通过一个指针去控制
         * @return
         */
        public int size() {
            return index;
        }
    
    
        /**
         * 判断是否为空
         *
         * @return
         */
        public boolean isEmpty() {
            return size() == 0;
        }
    
        /**
         * 集合新增元素
         * @param t
         */
        public void add(T t) {
            add(t, index);
        }
    
    
        /**
         * 集合指定位置新增元素,
         * ##private##
         * @param t
         * @param index
         */
        public void add(T t, int index) {
            // 如果数组的长度等于数组的指针,就扩容
            if (array.length == size()) {
                int newLength = array.length * 2 - 1;
                enlargeList(newLength);
                System.out.println("扩容到了" + newLength);
            }
            // 如果指定的位置大于list的长度,就还是把这个值add到集合的末尾
            if (index > size()) {
                index = size();
            }
            // 如果插入的位置在他之前,就需要把他之后的元素都向后移一位,然后插入
            if (index < size()) {
                for (int i = size(); i > index-1 ; i--) {
                    array[i] = array[i-1];
                }
            }
            array[index] = t;
            this.index++;
    
        }
    
        /**
         * 数组扩容
         * @param newSize
         */
        public void enlargeList(int newSize) {
            if (newSize < size()) {
                return;
            }
            T[] oldArr = array;
            array = (T[]) new Object[newSize];
            for (int i = 0; i < oldArr.length; i++) {
                array[i] = oldArr[i];
            }
        }
    
        /**
         * 获取下标为index的函数
         * @param index
         * @return
         */
        public T get(int index) {
            return array[index];
        }
    
    
        /**
         * 设置下表为 index 的值,并返回原来的值
         * @param index
         * @param newVal
         * @return
         */
        public T set(int index, T newVal) {
            if (index < 0 || index > size()) {
                throw  new IndexOutOfBoundsException();
            } else {
                T toReturn = array[index];
                array[index] = newVal;
                return toReturn;
            }
        }
    
        /**
         * 移除元素
         * 数组因为在内存中是连续的,所以删除的时候把这个元素的后一位前移一位都行
         * 这也是数组集合增删慢的原因
         * @param index
         * @return
         */
        public T remove(int index) {
            if (index < 0 || index > size()) {
                throw  new IndexOutOfBoundsException();
            } else {
                // 将后面每一位赋值到前一位
                T oldVal = array[index];
    
                for (int i = index; i < size()-1; i++) {
                    array[i] = array[i+1];
                }
    
                this.index--;
    
                return oldVal;
            }
        }
    
        public static void main(String[] args) {
            MyArrayList<Integer> list = new MyArrayList<Integer>(6);
    
            System.out.println(list.size());
    
            /** test1 start**/
    //        list.add(1);
    //        list.add(2);
    //        list.add(3);
    //        println(list);
    //        list.add(222,10);
    //        println(list);
            /** test1 end**/
    
            /** test2 start**/
            list.add(1);
            System.out.println(list.get(0));
            list.add(2);
            list.add(3);
            list.add(4);
            list.add(5);
            println(list);
    //        list.enlargeList(20);
            println(list);
            Integer oldVal = list.set(3, 20);
            System.out.printf("原来的值:%d", oldVal);
            System.out.println();
            println(list);
            Integer remove = list.remove(1);
            System.out.println(remove);
            println(list);
            /** test2 end**/
        }
    
        private static void println(MyArrayList list) {
            for (int i = 0; i < list.size(); i++) {
                System.out.print(list.get(i) + " ");
            }
            System.out.println();
        }
    
        /**
         * 基础知识:测试数组复制
         * 1.a = new int[...] 会把这个a与这个数组对象的引用断开,重新指向一个新的内存地址,
         *   但是b与a之前的数组对象还是存在引用,所以a重新分配对象并不会影响到b
         * 2.a[?] = ? 改变的仍是a指向的内存地址中的数据,由于b也是指向这个内存地址,所以这样操作会影响到b
         * @param args
         */
        public static void testCopy(String[] args) {
            int[] a = new int[]{1,2,4};
            println(a);
    
            int[] b = a;
    
            println(a);
            println(b);
    
            a = new int[2];
            println(a);
            println(b);
    
            int[] c = a;
    
            println(b);
            println(c);
    
            a[0] = 101;
            println(b);
            println(c);
    
    
        }
    
        private static void println(int[] list) {
            for (int aList : list) {
                System.out.print(aList + " ");
            }
            System.out.println("");
        }
    }
    
    

    改进了下

    package array;
    
    /**
     * @author ethan
     * @date 2019/10/21 09:03
     */
    @SuppressWarnings("unchecked")
    public class ArrayList<E> {
    
        /**
         * 元素的数量
         */
        private int size;
    
        /**
         * 所有元素
         */
        private E[] elements;
    
        private static final int DEFAULT_CAPACITY = 10;
        private static final int ELEMENT_NOR_FOUND = -1;
    
        public ArrayList(int size) {
            if (size <= 0) {
                size = DEFAULT_CAPACITY;
            }
            elements = (E[])new Object[size];
        }
    
        public ArrayList() {
            this(DEFAULT_CAPACITY);
        }
    
        public int size() {
            return size;
        }
    
    
        public boolean isEmpty() {
            return size == 0;
        }
    
        public boolean contains(E element) {
            int i = indexOf(element);
            if (i == ELEMENT_NOR_FOUND) {
                return false;
            }
            return true;
        }
    
        public int indexOf(E element) {
            if (element == null) {
                for (int i = 0; i < size; i++) {
                    if (elements[i] == null) {
                        return i;
                    }
                }
            } else {
                for (int i = 0; i < size; i++) {
                    if (element.equals(elements[i])) {
                        return i;
                    }
                }
            }
            return ELEMENT_NOR_FOUND;
        }
    
        public E get(int index) {
            rangeCheck(index);
            return elements[index];
        }
    
        public E set(int index, E element) {
    
            rangeCheck(index);
    
            E old = elements[index];
            elements[index] = element;
            return old;
        }
    
        public void add(E element) {
            add(size, element);
        }
    
        public void add(int index, E element) {
            rangeCheckForAdd(index);
    
            ensureCapacity(size + 1, elements.length);
    
            for (int i = size; i > index; i--) {
                elements[i] = elements[i-1];
            }
            elements[index] = element;
            size++;
        }
    
        private void ensureCapacity(int size, int length) {
            if (size > length) {
                E[] newElements = (E[]) new Object[length + (length >> 1)];
                for (int i = 0; i < size - 1; i++) {
                    newElements[i] = elements[i];
                }
                elements = newElements;
            }
        }
    
        public E remove(int index) {
            rangeCheck(index);
            E old = elements[index];
            for (int i = index + 1; i <= size - 1; i++) {
                elements[i - 1] = elements[i];
            }
            elements[--size] = null;
    
            return old;
        }
    
        public void clear() {
            for (int i = 0; i < size; i++) {
                elements[i] = null;
            }
            size = 0;
        }
    
        private void rangeCheck(int index) {
            if (index < 0 || index >= size) {
                throw new IndexOutOfBoundsException("index=" + index +", size=" + size);
            }
        }
    
        private void rangeCheckForAdd(int index) {
            if (index < 0 || index > size) {
                throw new IndexOutOfBoundsException("index=" + index +", size=" + size);
            }
        }
    
        @Override
        public String toString() {
    
            StringBuilder builder = new StringBuilder();
            builder.append("size=").append(size).append(", [");
            for (int i = 0; i < size; i++) {
                builder.append(elements[i]);
                if (i != size -1) {
                    builder.append(", ");
                }
            }
            builder.append("]");
            return builder.toString();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:手写简单的ArrayList

          本文链接:https://www.haomeiwen.com/subject/dfvmzqtx.html