我所理解的JKD集合类(三):手写ArrayList实现List接口

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

package cn.test;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * @Description : 手写ArrayList的实现
 * @Author : [email protected], 2016年5月1日 上午8:40:09
 * @Modified :[email protected], 2016年5月2日
 */
public class MyArrayList implements List {

    private int modCount; // 更新次数 -- eg: 遍历的时候使用list.remove()会报错。使用iterator.remove()不会报错

    private int size;

    private Object[] elementArray;

    private static final int DEFAULT_CAPACITY = 10;

    private static final int MAX_CAPACITY = 2^16;

    private static final double INCREMENT_FACTOR = 0.5;

    public MyArrayList(){
        this(DEFAULT_CAPACITY);
    }

    public MyArrayList(int capacity){
        if (capacity < 0) {
            throw new IllegalArgumentException("初始容量不合法");
        }

        if (capacity > MAX_CAPACITY) {
            capacity = MAX_CAPACITY;
        }

        elementArray = new Object[capacity];
    }

    public MyArrayList(Object[] array){
        elementArray = new Object[DEFAULT_CAPACITY];
        ifIncrement(array.length);
        System.arraycopy(array, 0, elementArray, 0, array.length);
        size = array.length;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean contains(Object o) {
        for (Object obj : elementArray) {
            if (obj.equals(o)) {
                return true;
            }
        }
        return false;
    }

    public Iterator iterator() {
        return new MyListIterator(0);
    }

    public Object[] toArray() {
        return Arrays.copyOf(elementArray, size);
    }

    public  T[] toArray(T[] a) {
        System.arraycopy(elementArray, 0, a, 0, Math.min(a.length, size));
        return a;
    }

    public boolean add(E e) {
        ifIncrement(1);
        elementArray[size] = e;
        size++;
        modCount++;
        return true;
    }

    public boolean remove(Object o) {
        int indexOf = indexOf(o);
        if (indexOf >= 0) {
            remove(indexOf);
            return true;
        }
        return false;
    }

    public boolean containsAll(Collection c) {
        for (Object object : c) {
            if (! contains(object)) {
                return false;
            }
        }
        return true;
    }

    public boolean addAll(Collection c) {
        ifIncrement(c.size());
        System.arraycopy(c.toArray(), 0, elementArray, size, c.size());

        size += c.size();
        modCount++;
        return true;
    }

    public boolean addAll(int index, Collection c) {
        if (index < 0) {
            return false;
        }
        if (index > size) {
            throw new IndexOutOfBoundsException();
        }

        Object[] objArray = c.toArray();

        ifIncrement(objArray.length);

        if (index == size) {
            return addAll(c);
        }

        System.arraycopy(elementArray, index, elementArray, (objArray.length + index), (size - index));
        System.arraycopy(objArray, 0, elementArray, index, objArray.length);

        size += objArray.length ;
        modCount++;
        return true;
    }

    public boolean removeAll(Collection c) {
        boolean flag = false;
        for (Object object : c) {
            if (remove(object)){
                flag = true;
            }
        }
        return flag;
    }

    // 交集
    public boolean retainAll(Collection c) {
        Object[] originalToArray = c.toArray();
        for(int i = 0; i < originalToArray.length; i++){
            for (int j = 0; j < elementArray.length; j++) {
                if (null != originalToArray && originalToArray[i].equals(elementArray[j])) {
                    elementArray[j] = null;
                    size--;
                    modCount++;
                    break;
                }
            }
        }
        return false;
    }

    public void clear() {
        Arrays.fill(elementArray, null);
        size = 0;
        modCount++;
    }

    @SuppressWarnings("unchecked")
    public E get(int index) {
        return (E)elementArray[index];
    }

    public E set(int index, E element) {
        if (index >= size) {
            ifIncrement(index-size + 1);
        }
        elementArray[index] = element;
        return element;
    }

    public void add(int index, E element) {
        if (index > size) {
            throw new IndexOutOfBoundsException("越界啦");
        }else
        if (index == size) {
            add(element);
            return;
        }else {
            ifIncrement(1);
            System.arraycopy(elementArray, index, elementArray, index + 1, size - index);
            elementArray[index] = element;
            size++;
            modCount++;
        }
    }

    @SuppressWarnings("unchecked")
    public E remove(int index) {
        Object object = elementArray[index];

        Object[] tempArray = Arrays.copyOfRange(elementArray, index+1, size);
        System.arraycopy(tempArray, 0, elementArray, index, tempArray.length);
        size--;
        elementArray[size] = null;

        modCount++;
        return (E)object;
    }

    public int indexOf(Object o) {
        for (int i = 0; i < size; i++) {
            if (elementArray[i].equals(o)) {
                return i;
            }
        }
        return -1;
    }

    public int lastIndexOf(Object o) {
        for (int i = size - 1; i >= 0; i--) {
            if (elementArray[i].equals(o)) {
                return i;
            }
        }
        return -1;
    }

    public ListIterator listIterator() {
        return new MyListIterator(0);
    }

    public ListIterator listIterator(int index) {
        return new MyListIterator(index);
    }

    public List subList(int fromIndex, int toIndex) {
        Object[] tempArray = new Object[toIndex - fromIndex + 1];

        System.arraycopy(elementArray, fromIndex, tempArray, 0, tempArray.length);
        return new MyArrayList(tempArray);
    }


    private void ifIncrement(int a){
        if (elementArray.length < size + a) {
            // 扩容
            elementArray = Arrays.copyOf(elementArray, Math.max((int)(elementArray.length * (1 + INCREMENT_FACTOR)), size + a));
        }
    }

    @SuppressWarnings("unchecked")
    private class MyListIterator implements ListIterator {

        private int itrModCount = modCount;

        private int lastReturnedIndex = -1;

        private int nextReturnIndex;

        public MyListIterator (int index) {
            this.nextReturnIndex = index;
        }

        @Override
        public boolean hasNext() {
            return nextReturnIndex != size;
        }

        @Override
        public E next() {
            checkModCount();
            E e = (E)elementArray[nextReturnIndex];
            lastReturnedIndex = nextReturnIndex++;
            return e;

        }

        public boolean hasPrevious() {
            return lastReturnedIndex != -1;
        }

        public E previous() {
            checkModCount();
            E e = (E)elementArray[lastReturnedIndex--];
            nextReturnIndex--;
            return e;
        }

        public int nextIndex() {
            return nextReturnIndex;
        }

        public int previousIndex() {
            return lastReturnedIndex;
        }

        public void remove() {
            checkModCount();
            MyArrayList.this.remove(lastReturnedIndex);
            lastReturnedIndex = -1;

            modCount++;
            itrModCount = modCount;
        }

        public void set(E e) {
            checkModCount();
            MyArrayList.this.set(lastReturnedIndex, e);
        }

        public void add(E e) {
            checkModCount();
            MyArrayList.this.add(lastReturnedIndex + 1, e);
            nextReturnIndex++;

            modCount++;
            itrModCount = modCount;
        }

        private void checkModCount(){
            if (this.itrModCount != MyArrayList.this.modCount) throw new RuntimeException("遍历期间不能增删元素,如果需要,请使用iterator的函数");
        }
    }
}

ArrayList的底层是通过数组来实现的。数组的扩容时的复制采用的System.copyArray(),该方法是操作系统级别的native的操作,尽量使数组的操作更有效率。

转载于:https://my.oschina.net/u/3466682/blog/1577583

你可能感兴趣的:(我所理解的JKD集合类(三):手写ArrayList实现List接口)