Thinking in java 讀書筆記(八.2:abstractCollection、List和AbstractList閱讀)

AbstractCollection繼承collection,只抽象了兩個方法,因爲其他方法基本都是可以使用迭代器實現的。
而List接口是增加了八個接口,兩個ListIterator方法(ListIterator是可以雙向遍歷的一種迭代器,只適用於list),兩個搜索操作(indexOf,lastIndexof),四個Positional Access Operations。

AbstractList感覺是精華啊,這個類裏面實現了Iterator和ListIterator,ListIterator是隻用於list的迭代器,提供向前遍歷的功能。然後是一層一層抽象下來,到abstractList爲止,只剩下最基本的增刪改查(add(int index, E element), remove(int index),set(int index, E element),public E get)沒有實現,其他的方法都已經實現好了。也就是說其他所有的邏輯都可以通過這四個方法組合。好特麼厲害啊,邏輯清晰而且代碼複用率高。
還有一點很出乎意料的就是sublist,本來還以爲sublist會新建一個list然後將元素添加進去,結果原來是直接持有原來的對象,僅僅是限制了下標。其實仔細想想也應該的,如果再添加一次不是白白浪費計算時間了= =。

還有一點就是RandomAccess接口的用處。
RandomAccess是用來標記collection的,如果某個容器實現了這個接口,那麼這個容器更適合使用for循環來遍歷,

AbstractCollection兩個地方比較注意,一個是對於數組越界的處理,一個是數組容量的處理。emmm只能說寫的真的很嚴謹= =。

public abstract class MyAbstractCollection<E> implements MyCollection<E> {
    protected MyAbstractCollection(){}

    public abstract Iterator<E> iterator();

    public abstract int size();

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

    @Override
    public boolean contains(Object o) {
        Iterator<E> iterator = iterator();
        if (o==null){
            //當collection爲null,輸入爲null時返回true
            while (iterator.hasNext()){
                if (iterator.next()==null){
                    return true;
                }
            }
        }else {
            while (iterator.hasNext()){
                if (o.equals(iterator.next())){
                    return true;
                }
            }
        }
        return false;
    }

    /*將list以數組的形式返回*/
    @Override
    public Object[] toArray() {
        Object[] r = new Object[size()];//定義一個等大小的數組
        Iterator<E> iterator = iterator();
        for (int i=0;i<r.length;i++){
            if (!iterator.hasNext()){
                //如果list中的實際元素數量小於size。爲什麼會有這種情況?會因爲因爲多線程搞成這樣?
                //返回實際元素的數組.
                return Arrays.copyOf(r,i);
            }
            r[i] = iterator.next();
        }
        //如果實際元素特麼的比size多,返回finishToArray
        //是爲什麼會存在實際元素更多的情況。
        return iterator.hasNext()? finishToArray(r,iterator): r;

    }

       @Override
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        int size = size();
        //使用反射來創建數組
        T[] r = a.length >= size ? a :
                (T[])java.lang.reflect.Array
                        .newInstance(a.getClass().getComponentType(), size);
        Iterator<E> it = iterator();

        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) { // collection中的數量小於期望值
                if (a == r) {
                    r[i] = null; // null-terminate
                } else if (a.length < i) {
                    return Arrays.copyOf(r, i);
                } else {
                    System.arraycopy(r, 0, a, 0, i);
                    if (a.length > i) {
                        a[i] = null;
                    }
                }
                return a;
            }
            r[i] = (T)it.next();
        }
        // more elements than expected
        return it.hasNext() ? finishToArray(r, it) : r;
    }

    //爲什麼要-8呢,因爲這是個對象數組,而不是一個基礎類型的數組,需要留有空間來描述這個對象
    //The object header consists of a mark word and a klass pointer.
    //The mark word has word size (4 byte on 32 bit architectures, 8 byte on 64 bit architectures) and
    //the klass pointer has word size on 32 bit architectures. On 64 bit architectures the klass pointer either has word size,
    // but can also have 4 byte if the heap addresses can be encoded in these 4 bytes.
    /**
     * @see <a href="https://stackoverflow.com/questions/35756277/why-the-maximum-array-size-of-arraylist-is-integer-max-value-8">
     *     爲什麼數組最大值減8</a>
     * */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;


    @SuppressWarnings("unchecked")
    private static <T> T[] finishToArray(T[] r,Iterator<?> iterator){
        int i = r.length;
        while (iterator.hasNext()){
            int cap = r.length;
            if (i == cap){
                //數組擴容
                int newCap = cap + (cap >> 1)+1;
                //擴容後的數組容量過大,
                if (newCap-MAX_ARRAY_SIZE>0){
                    newCap = hugeCapacity(cap+1);
                }
                //擴容後數組轉移
                r = Arrays.copyOf(r,newCap);
            }
            r[i++] = (T)iterator.next();
        }
        // trim if overallocated
        return (i==r.length)? r: Arrays.copyOf(r,i);
    }

    private static int hugeCapacity(int minCapacity){
        if(minCapacity < 0 ){//意味着大於MaxInteger了
            throw new OutOfMemoryError("Required array size too large");
        }
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }

    /*爲什麼一直拋出異常= =*/
    @Override
    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

    /**
     * 能用迭代器解決的問題都用迭代器些了
     * */
    @Override
    public boolean remove(Object o) {
        Iterator<E> iterator = iterator();
        if (o == null){
            while (iterator.hasNext()){
                if (iterator.next() == null){
                    iterator.remove();
                    return true;
                }
            }
        }else {
            while (iterator.hasNext()){
                if (o.equals(iterator.next())){
                    iterator.remove();
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean containsAll(MyCollection<?> collection) {
        for (Object o:collection){
            if (!contains(o))
                return false;
        }
        return true;
    }

    //所以這裏其實是只要有改變就返回true,而不需要全部確認插入
    @Override
    public boolean addAll(MyCollection<? extends E> collection) {
        boolean modified = false;
        for (E e:collection){
            if (add(e))
                modified = true;
        }
        return modified;
    }

    //寫到這裏下意識remove的時候想調用class中的remove方法= =,但是這樣會多遍歷一遍
    @Override
    public boolean removeAll(MyCollection<?> collection) {
        if (collection == null)
            throw new NullPointerException();
        boolean modified = false;
        Iterator<E> iterator = iterator();
        while (iterator.hasNext()){
            if (collection.contains(iterator.next())){
                iterator.remove();
                modified = true;
            }
        }
        return modified;
    }

    @Override
    public void clear() {
        Iterator<E> iterator = iterator();
        while (iterator.hasNext()){
            iterator.next();
            iterator.remove();
        }
    }

    @Override
    public String toString() {
        Iterator<E> iterator = iterator();
        if (! iterator.hasNext())
            return "[]";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append('[');
        for (;;){
            E e = iterator.next();
            stringBuilder.append(e == this?"(this collection)":e);
            if (!iterator.hasNext())
                return stringBuilder.append(']').toString();
            stringBuilder.append(',').append(' ');
        }
    }
}

public interface List<E> extends MyCollection<E>{
    @Override
    int size();

    @Override
    boolean isEmpty();

    @Override
    boolean contains(Object o);

    @Override
    Iterator iterator();

    @Override
    Object[] toArray();

    @Override
    Object[] toArray(Object[] a);

    @Override
    boolean add(Object o);

    @Override
    boolean remove(Object o);

    @Override
    boolean containsAll(MyCollection collection);

    @Override
    boolean addAll(MyCollection collection);

    boolean addAll(int index, MyCollection<? extends E> collection);

    @Override
    boolean removeAll(MyCollection collection);

    @Override
    void clear();

    @Override
    int hashCode();

    @Override
    boolean equals(Object o);


    E get(int index);

    E set(int index,E element);

    void add(int index,E element);

    E remove(int index);

    int indexOf(Object o);

    int lastIndexOf(Object o);

    ListIterator<E> listIterator();

    ListIterator<E> listIterator(int index);
//具體的迭代器在這個abstract中實現。
public abstract class MyAbstractList<E> extends MyAbstractCollection<E>
        implements MyList<E> {



    protected MyAbstractList(){}


    //Iterators


    //修飾該變量不需要參與序列化過程,
    //用於記錄該容器的修改次數
    protected transient int modCount = 0;


    private class Itr implements Iterator<E>{

        //這裏的cursor = next;lastRet=current;
        int cursor = 0;

        int lastRet = -1;

        int expectedModeCount = modCount;

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

        @Override
        public E next() {
            checkDorComodification();
            try {
                int i= cursor;
                E next = get(i);
                lastRet = i;
                cursor = i+1;
                return next;
            }catch (IndexOutOfBoundsException e){
                checkDorComodification();
                throw new NoSuchElementException();
            }

        }

        final  void checkDorComodification(){
            if (modCount != expectedModeCount)
                throw new ConcurrentModificationException();
        }
    }

    private class ListItr extends Itr implements ListIterator<E>{

        //cursor = next;
        ListItr(int index){
            cursor = index;
        }

        @Override
        public boolean hasPrevious() {
            return cursor!=0;
        }

        @Override
        public E previous() {
            checkDorComodification();
            try {
                int i = cursor-1;
                E privious = get(i);
                lastRet = cursor = i;
                return privious;
            }catch (IndexOutOfBoundsException e){
                checkDorComodification();
                throw new NoSuchElementException();
            }

        }

        @Override
        public int nextIndex() {
            return cursor;
        }

        @Override
        public int previousIndex() {
            return cursor-1;
        }

        @Override
        public void remove() {
            if (lastRet<0)
                throw new IllegalStateException();
            checkDorComodification();

        }

        @Override
        public void set(E e) {
            if (lastRet<0){
                throw new IllegalStateException();
            }
            checkDorComodification();
            try {
                MyAbstractList.this.set(lastRet,e);
                expectedModeCount = modCount;
            }catch (IndexOutOfBoundsException e1){
                throw new ConcurrentModificationException();
            }
        }


        @Override
        public void add(E e) {
            checkDorComodification();
            try{
                int i = cursor;
                MyAbstractList.this.add(i,e);
                lastRet = -1;
                cursor = i+1;
                expectedModeCount = modCount;
            }catch (IndexOutOfBoundsException ex){
                throw new ConcurrentModificationException();
            }
        }
    }

    @Override
    public Iterator<E> iterator() {
        return new Itr();
    }

    @Override
    public ListIterator<E> listIterator() {
        return listIterator(0);
    }

    @Override
    public ListIterator<E> listIterator(final int index) {
        rangeCheckForAdd(index);
        return new ListItr(index);
    }

    private void rangeCheckForAdd(int index){
        if (index<0||index>size()){
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    }







    //能用方法互相調用的,就不要用到持有的屬性,
    //比如說這裏要是我自己寫,,,一定是又寫一遍邏輯
    //這麼想其實邏輯相近的接口互相調用着實現,能省很多的代碼= =。
    public boolean add(E e) {
         add(size(),e);
        return true;
    }

    abstract public E get(int index);

    @Override
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    @Override
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int indexOf(Object o) {
        ListIterator<E> iterator = listIterator();
        if(o == null){
            while (iterator.hasNext()){
                if (iterator.next()==null){
                    return iterator.previousIndex();
                }
            }
        }else {
            while (iterator.hasNext()){
                if (o.equals(iterator.next()))
                    return iterator.previousIndex();
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(Object o) {
        ListIterator<E> iterator = listIterator(size());
        if (o==null){
            while (iterator.hasPrevious()){
                if (iterator.previous()==null)return iterator.nextIndex();
            }
        }
        else {
            while (iterator.hasPrevious()){
                if (o.equals(iterator.previous())){
                    return iterator.nextIndex();
                }
            }
        }
        return -1;
    }

    @Override
    public void clear() {
        removeRange(0,size());
    }

    @Override
    public boolean addAll(int index, MyCollection<? extends E> collection) {
        rangeCheckForAdd(index);
        boolean modified =false;
        for (E e:collection){
            add(index++,e);
            modified = true;
        }
        return modified;
    }

    protected void removeRange(int fromIndex, int toIndex){
        ListIterator<E> listIterator = listIterator(fromIndex);
        for (int i=0,n=toIndex-fromIndex;i<n;i++){
            listIterator.next();
            listIterator.remove();
        }
    }

    @Override
    public boolean equals(Object obj) {
        //不是本身並且是list的子類的情況下使用迭代器一個個比對數據
        if (obj == this)return true;
        if (!(obj instanceof MyList))
            return false;
        ListIterator<E> e1 = listIterator();
        ListIterator<?> e2 = ((MyList<?>)obj).listIterator();
        while (e1.hasNext() && e2.hasPrevious()){
            E o1 = e1.next();
            Object o2 = e2.next();
            //不知道嘛時候寫邏輯的時候我能馬上想到這樣寫= =
            if (!(o1==null ? o2 == null : o1.equals(o2)))
                return false;
        }
        //長度不一樣
        return !(e1.hasNext()||e2.hasNext());
    }

    @Override
    public int hashCode() {
        int hashcode = 1;
        for (E e:this){
            hashcode = 31*hashcode+(e==null?0:e.hashCode());
        }
        return hashcode;
    }

    private String outOfBoundsMsg(int index){
        return "Index: "+index+", Size: "+size();
    }


}

//本來還以爲sublist會新建一個list然後將元素添加進去,
// 結果原來是直接持有原來的對象,僅僅是限制了下標。
class MySubList<E> extends MyAbstractList<E>{
    private final MyAbstractList<E> l;
    private final int offset ;
    private int size ;

    MySubList(MyAbstractList<E> list,int fromIndex,int toIndex){
        if (fromIndex<0){
            throw new IndexOutOfBoundsException("fromIndex = "+fromIndex);
        }
        if (toIndex>list.size()){
            throw new IndexOutOfBoundsException("toIndex = "+toIndex);
        }
        if (fromIndex > toIndex){
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                    ") > toIndex(" + toIndex + ")");
        }
        l = list;
        offset = fromIndex;
        size = toIndex-fromIndex;
        this.modCount = l.modCount;
    }

    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

    private void checkForComodification() {
        if (this.modCount != l.modCount)
            throw new ConcurrentModificationException();
    }

    private void rangeCheck(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    //真是每次都需要檢查一遍越界異常哦,,,
    @Override
    public E get(int index) {
        rangeCheck(index);
        checkForComodification();
        return l.get(index+offset);
    }

    @Override
    public E set(int index, E element) {
        rangeCheck(index);
        checkForComodification();
        return l.set(index+offset, element);
    }

    @Override
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        checkForComodification();
        l.add(index+offset,element);
        this.modCount = l.modCount;
        size++;
    }

    @Override
    public E remove(int index) {
        rangeCheck(index);
        checkForComodification();
        E result = l.remove(index+offset);
        this.modCount = l.modCount;
        size--;
        return result;
    }

    @Override
    protected void removeRange(int fromIndex, int toIndex) {
        checkForComodification();
        l.removeRange(fromIndex+offset,toIndex+offset);
        this.modCount = l.modCount;
        size -= (toIndex-fromIndex);
    }

    @Override
    public boolean addAll(MyCollection<? extends E> collection) {
        return addAll(size,collection);
    }

    @Override
    public boolean addAll(int index, MyCollection<? extends E> collection) {
        rangeCheck(index);
        int cSize = collection.size();
        if (cSize==0)return false;
        checkForComodification();
        l.addAll(offset+index,collection);
        this.modCount = l.modCount;
        size+=cSize;
        return true;
    }

    @Override
    public Iterator<E> iterator() {
        return listIterator();
    }

    @Override
    public ListIterator<E> listIterator(final int index) {
        checkForComodification();
        rangeCheckForAdd(index);

        return new ListIterator<E>() {
            private final ListIterator<E> iterator = l.listIterator(index+offset);


            @Override
            public boolean hasNext() {
                return nextIndex()<size;
            }

            @Override
            public E next() {
                if (hasNext())
                    return iterator.next();
                else
                    throw new NoSuchElementException();
            }

            @Override
            public boolean hasPrevious() {
                return previousIndex()>=0;
            }

            @Override
            public E previous() {
                if (hasPrevious())
                    return iterator.previous();
                else
                    throw new NoSuchElementException();
            }

            @Override
            public int nextIndex() {
                return iterator.nextIndex()-offset;
            }

            @Override
            public int previousIndex() {
                return iterator.previousIndex()-offset;
            }

            @Override
            public void remove() {
                iterator.remove();
                MySubList.this.modCount = l.modCount;
                size--;
            }

            @Override
            public void set(E e) {
                iterator.set(e);
            }

            @Override
            public void add(E e) {
                iterator.add(e);
                MySubList.this.modCount = l.modCount;
                size++;
            }
        };
    }

    @Override
    public MyList<E> subList(int fromIndex, int toIndex) {
        return new MySubList<E>(this, fromIndex, toIndex);
    }

    @Override
    public int size() {
        checkForComodification();
        return size;
    }
}

class RandomAccessSublist<E> extends MySubList<E> implements RandomAccess{

    RandomAccessSublist(MyAbstractList<E> list, int fromIndex, int toIndex) {
        super(list, fromIndex, toIndex);
    }
    public MyList<E> subList(int fromIndex, int toIndex) {
        return new RandomAccessSublist<E>(this, fromIndex, toIndex);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章