美文网首页
动态数组

动态数组

作者: GeekAmI | 来源:发表于2018-07-16 22:07 被阅读15次
    1. 手动实现版本
    public class Array<E> {
    
        private E[] data;
        private int size;
    
        public Array(int capacity) {
            data = (E[]) new Object[capacity];
            size = 0;
        }
    
        public Array() {
            this(10);
        }
    
        public void add(int index, E e) {
            if (index < 0 || index > size) {
                throw new RuntimeException("Illegal index, index should in[0, size]!");
            }
            //动态扩容
            if (size >= data.length) {
                resize(2 * data.length);
            }
            for (int i = size - 1; i >= index; i--) {
                data[i + 1] = data[i];
            }
            data[index] = e;
            size++;
        }
    
        public void addFirst(E e) {
            add(0, e);
        }
    
        public void addLast(E e) {
            add(size, e);
        }
    
        public int find(E e) {
            for (int i = 0; i < size; i++) {
                if (data[i].equals(e)) {
                    return i;
                }
            }
            return -1;
        }
    
        public boolean contains(E e) {
            for (int i = 0; i < size; i++) {
                if (data[i].equals(e)) {
                    return true;
                }
            }
            return false;
        }
    
        public E get(int index) {
            if (index < 0 || index >= size) {
                throw new RuntimeException("Illegal index, index should in[0, size)!");
            }
            return data[index];
        }
    
        public E getFirst() {
            return data[0];
        }
    
        public E getLast() {
            return data[size - 1];
        }
    
        public void set(int index, E e) {
            if (index < 0 || index >= size) {
                throw new RuntimeException("Illegal index, index should in[0, size)!");
            }
            data[index] = e;
        }
    
        public E remove(int index) {
            if (index < 0 || index >= size) {
                throw new RuntimeException("Illegal index, index should in[0, size)!");
            }
            E ret = data[index];
            for (int i = index + 1; i < size; i++) {
                data[i - 1] = data[i];
            }
            size--;
            // azy缩容
            if (size == data.length / 4 && data.length / 2 != 0) {
                resize(data.length / 2);
            }
            return ret;
        }
    
        public E removeFirst() {
            return remove(0);
        }
    
        public E removeLast() {
            return remove(size - 1);
        }
    
        public void remove(E e) {
            int index = find(e);
            if (index != -1) {
                remove(index);
            }
        }
    
        public int getCapacity() {
            return data.length;
        }
    
        public boolean isEmpty() {
            return size == 0;
        }
    
        public int getSize() {
            return size;
        }
    
        private void resize(int newCapacity) {
            if (newCapacity < size) {
                throw new RuntimeException("Illegal newCapacity, newCapacity should >= size");
            }
            E[] newData = (E[]) new Object[newCapacity];
    
            for (int i = 0; i < size; i++) {
                newData[i] = data[i];
            }
            data = newData;
        }
    
        @Override
        public String toString() {
            StringBuilder res = new StringBuilder();
            res.append("Array size:" + size + ", capacity:" + data.length + "\n");
            res.append("data[");
            for (int i = 0; i < size; i++) {
                res.append(data[i] + " ");
            }
            res.append("]");
            return res.toString();
        }
    }
    
    1. JDK版本分析

    2.1 需要扩容时,变为原来的1.5倍

    public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
    }
    
    private void ensureCapacityInternal(int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
    
      private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
    

    2.2 通过垃圾回收,动态缩容

        public E remove(int index) {
            rangeCheck(index);
    
            modCount++;
            E oldValue = elementData(index);
    
            int numMoved = size - index - 1;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--size] = null; // clear to let GC do its work
    
            return oldValue;
        }
    

    总结:还是JDK写的漂亮啊🤣

    相关文章

      网友评论

          本文标题:动态数组

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