Java基礎隨筆1

來源:互聯網
上載者:User

標籤:固定   定位   hid   構造器   sub   ado   功能   clone   oid   

最近準備跳槽了,可能要從安卓轉做javaweb,抓緊時間複習一下java的基礎內容。正好在github上發現了crossoverJie的Java-Interview項目,就來逐項學習一下。

————————————————————————————————————————————————————————————————————————————

ArrayList/Vector 的底層分析ArrayList

ArrayList 實現於 ListRandomAccess 介面。可以插入空資料,也支援隨機訪問。

ArrayList相當於動態資料,其中最重要的兩個屬性分別是: elementData 數組,以及 size 大小。 在調用 add() 方法的時候:

    public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }
  • 首先進行擴容校正。
  • 將插入的值放到尾部,並將 size + 1 。

如果是調用 add(index,e) 在指定位置添加的話:

    public void add(int index, E element) {        rangeCheckForAdd(index);        ensureCapacityInternal(size + 1);  // Increments modCount!!        //複製,向後移動        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);        elementData[index] = element;        size++;    }
  • 也是首先擴容校正。
  • 接著對資料進行複製,目的是把 index 位置空出來放本次插入的資料,並將後面的資料向後移動一個位置。

其實擴容最終調用的代碼:

    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);    }

也是一個數組複製的過程。

由此可見 ArrayList 的主要消耗是數組擴容以及在指定位置添加資料,在日常使用時最好是指定大小,盡量減少擴容。更要減少在指定位置插入資料的操作。

序列化

由於 ArrayList 是基於動態數組實現的,所以並不是所有的空間都被使用。因此使用了 transient 修飾,可以防止被自動序列化。

transient Object[] elementData;

因此 ArrayList 自訂了序列化與還原序列化:

    private void writeObject(java.io.ObjectOutputStream s)        throws java.io.IOException{        // Write out element count, and any hidden stuff        int expectedModCount = modCount;        s.defaultWriteObject();        // Write out size as capacity for behavioural compatibility with clone()        s.writeInt(size);        // Write out all elements in the proper order.        //只序列化了被使用的資料        for (int i=0; i<size; i++) {            s.writeObject(elementData[i]);        }        if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }    }    private void readObject(java.io.ObjectInputStream s)        throws java.io.IOException, ClassNotFoundException {        elementData = EMPTY_ELEMENTDATA;        // Read in size, and any hidden stuff        s.defaultReadObject();        // Read in capacity        s.readInt(); // ignored        if (size > 0) {            // be like clone(), allocate array based upon size not capacity            ensureCapacityInternal(size);            Object[] a = elementData;            // Read in all elements in the proper order.            for (int i=0; i<size; i++) {                a[i] = s.readObject();            }        }    }

當對象中自訂了 writeObject 和 readObject 方法時,JVM 會調用這兩個自訂方法來實現序列化與還原序列化。

從實現中可以看出 ArrayList 只序列化了被使用的資料。

以上為複製git的內容。下面解釋一下其中我不太熟悉和明白的內容。

————————————————————————————————————————————————————————————

一、ArrayList

首先是ArrayList基礎,ArrayList指的就是動態數組,包括三個主要的優點:

  動態增加和減少元素 
  實現了ICollection和IList介面 
  靈活的設定數組的大小

ArrayList有三個構造器,分別是public ArrayList(); public ArrayList(ICollection); public ArrayList(int); (第一個構造器預設按照16的大小構造,第二個將該集合的元素添加到ArrayList,第三個按照參數構造)。

IsSynchronized屬性指示當前的ArrayList執行個體是否支援線程同步,而ArrayList.Synchronized靜態方法則會返回一個ArrayList的線程同步的封裝。 (先放這,線程問題後面再詳細解釋)

TrimSize方法用於將ArrayList固定到實際元素的大小,當動態數組元素確定不在添加的時候,可以調用這個方法來釋放空餘的記憶體。

效率問題:

1.數組擴容是對ArrayList效率影響比較大的一個因素。 每當執行Add、AddRange、Insert、InsertRange等添加元素的方法,都會檢查內部數組的容量是否不夠了,會以當前容量的兩倍來重新構建一個數組,將舊元素Copy到新數組中,然後丟棄舊數組。如果不運行TrimSize方法或者儲存元素不足填滿,會造成較大的記憶體浪費。

2.調用IndexOf、Contains等方法是執行的簡單的迴圈來尋找元素,會造成效率低下的問題,還不如自己手寫演算法進行尋找。

二、List介面

List介面中可以存放任意的資料。而且在List介面中內容是允許重複的。List介面的功能要比Collection介面強大很多,因為大量擴充了Collection介面的操作。擴充方法:1、public void add(int index,E element)普通  在指定的位置增加元素。2、public boolean addAll(int index, Collection<? extends E> c)  普通 在指定的位置增加一組元素。3、E get(int index) 普通 返回指定位置的元素。4、public int indexOf(Object o) 普通 尋找指定元素的位置。5、public int lastIndexOf(Object o) 普通 從後向前尋找指定元素的位置。6、public ListIterator<E> listIterator()普通 為ListIterator介面執行個體化。7、public E remove(int index) 普通 按指定的位置刪除元素。8、public List<E> subList(int fromIndex, int toIndex) 普通 取出集合中的子集合。9、public E set(int index, E element)普通 替換指定位置的元素。 三、RandomAccess介面RandomAccess 是一個標記介面,用於標明實現該介面的List支援快速隨機訪問,主要目的是使演算法能夠在隨機和順序訪問的list中表現的更加高效。  

 

Java基礎隨筆1

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.