看看熟悉的ArrayList的源碼 Java 9

    往下繼續就是咱們用的比較多的ArrayList類了,相信說本身學過Java的都接觸過這個類吧,實現的接口有Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess,這個類和Vector很像,只是這個不是線程安全的。簡單地說這類就是能夠調節大小的數組,能夠存儲全部元素,包括null。數組

    若是多個線程同時訪問ArrayList實例,而且至少有一個線程在結構上修改了該列表,則必須在外部同步該List。(結構修改是添加或刪除一個或多個元素或顯式調整支持數組大小的任何操做;僅設置元素的值並非結構修改。)。這一般是經過對一些封裝LIst的對象進行同步來實現的。若是不存在這樣的對象,則應該使用Collectiontions.synizedList方法「包裝」列表。最好在建立時這樣作,以防止意外地不一樣步地訪問列表:安全

   List list = Collections.synchronizedList(new ArrayList(...));app

    有三個構造方法,第一個空的,第二個有容量大小的,這個能夠根據實際的大小須要,畢竟擴容是個比較消耗性能的操做;第三個能夠把Collection做爲參數傳進去,這個方法的實現,比LinkedList簡單,調用了Arrays.copyOf方法。dom

    看到一個trimToSize方法,能夠將List的容量變得和自身大小一致,看來Arrays.copyOf這個方法真的很好用函數

    還有一個方法用來擴充容量的,可是這裏有一個參數minCapacity,看註釋比較難理解(增長ArrayList的容量,以確保它可以至少保持元素的數量,由最小容量參數指定),仍是進入方法看一下吧。minCapacity要比如今容量大,而且當前容量不是空而且minCapacity大於默認值。性能

    在grow方法中執行Arrays.copyOf(elementData,newCapacity(minCapacity) ,其實這裏重要的是看 newCapacity方法 ,newCapatity是原來的1.5倍,若是newCapacity不比minCapacity大,若是是空,那麼返回默認容量和minCapaticy中大的那個,若是minCapaticy小於0,竟然返回OutMemoryError異常也是神奇,其餘返回minCapacity;另外一種是newCapacity比minCapaticy大,若是newCapacity不比MAX_ARRAY_SIZE大,那麼返回newCapacity,不然擴大minCapaticy到Integer.MAX_VALUE或者MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8)(很繞,對不對)學習

    其餘咱們經常使用的方法size,isempty,contains實現起來比較簡單,indexOf數組的隨機訪問,這個時間複雜度就比LinkedList這種鏈表結構的時間複雜度低了,雖然不知道這種底層是怎麼實現的。線程

 

    下面這個方法好像基本沒用過吧,這裏描述是個shallow copy,就是裏面的對象並非在內存中真的開闢了一個空間,若是不是Cloneable的就會拋出下面的異常。3d

    這裏是經常使用的get,set,add接口,get方法先調用Objects.checkIndex(index, size);沒想到Objects裏面還有這種方法 ,學習了,而後調用了elementData方法,獲取數組裏面index位置的值。 set方法也是相似,更換數組某個位置的值,返回老的值,可是add方法會判斷數組的長度和容量是否相等,若是不夠了那麼對調用grow()方法擴容,後面就是newCapacity(int minCapacity)方法的實現,因此add多是比較消耗性能的。對象

        其中remove方法,能夠根據index和object方法,只是時間複雜度都是線性的。由於看下面的方法,刪除某一個位置的數據之後,會作一個System.arraycopy。刪除object會遍歷數組,固然若是數組夠大的話,那麼這個也是挺耗時間的,方法和其餘刪除也是相似的,這裏是用的fastRemove,而後作複製的操做,其餘的removeRange也是相似的,神奇的是裏面還有一個batchRemove方法。

    而後看看clear方法,這裏就是把數組裏面的每一個值設置爲 null,可是若是容量已經很大的話,也不會作處理。

       看看sort方法作了什麼吧,用的是Arrays.sort((E[]) elementData, 0, size, c)方法。而後咱們再看一眼函數式接口

 

    而後看點不同的接口吧,好比入參是Consumer<? super E> action接口的,而後執行action.accept操做的。

       還有使用Predicate<? super E> filter,其實這裏用的是filter.test方法是否成立的謂詞邏輯。

    最後看一眼replaceAll裏面的operator.apply方法操做吧

   有什麼討論的內容,能夠加我公衆號:

相關文章
相關標籤/搜索