Java 集合框架(二)—— ArrayList
二、數組列表 —— ArrayList
1、構造方法
ArrayList 是 Java 中的動態數組,底層實現就是對象數組,只不過數組的容量會根據情況來改變。
它有個帶 int 類型參數的構造方法,根據傳入的參數,擴展初始化的數組容量,這個方法是推薦使用的,因為如果預先知道數組的容量,可以設置好初始值,而不用等每次容量不夠而擴容,減少 Arrays.copyOf 的次數:
它的很多方法的實現都是依靠 Arrays 這個工具類完成的,足以體現它與數組之間的密切關系。
比如有個帶 Collection 類型的構造方法,實現如下:
2、常用方法
1) ?trimToSize 方法
Trims the capacity of this ArrayList instance to be the list's current size.
An application can use this operation to minimize the storage of an ArrayList instance.
該方法可以去掉 ArrayList 占用的多余的空間或內存,因為 ArrayList 每次擴容后總會有所剩余,如果數組很大,占用的多余的空間會比較大,內存不夠時可以使用此方法。
2)ensureCapacity 方法
public void ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
除了在初始化 ArrayList 的時候可以事先定義一個給定的容量之外,還可以用此方法提高 ArrayList 的初始化速度。看下面的例子:
1 public static void main(String[] args) { 2 int n = 100000; 3 String str = "hello google"; 4 5 // 沒有調用 ensureCapacity() 方法初始化 ArrayList 對象 6 ArrayList<String> list = new ArrayList<>(); 7 long startTime = System.currentTimeMillis(); 8 for (int i = 0; i <= n; i++) { 9 list.add(str); 10 } 11 long endTime = System.currentTimeMillis(); 12 System.out.println("time: " + (endTime - startTime) + " ms"); 13 14 // 調用 ensureCapacity() 方法初始化 ArrayList 對象 15 list = new ArrayList<>(); 16 startTime = System.currentTimeMillis(); 17 list.ensureCapacity(n); 18 for (int i = 0; i < n; i++) { 19 list.add(str); 20 } 21 endTime = System.currentTimeMillis(); 22 System.out.println("time: " + (endTime - startTime) + " ms"); 23 }
結果為:
3)isEmpty 方法
注意此方法是判斷是否為空,不是是否為 null
public boolean isEmpty() {return size == 0; }
4)indexOf 、lastIndexOf 和 contain 方法
indexOf 方法返回 list 中首次出現給定對象的索引值(從 0 開始),如果不存在則返回 -1。
lastIndexOf 方法返回 list 中最后一次出現給定對象的索引值(從 size - 1 開始),如果不存在則返回 -1。
contain 方法 參數為 Object o,判斷 list 中是否包含給定的對象,存在則返回 true,源碼如下:
5)add,get 和 set 方法
三個很簡單的方法,區別在于:add 方法是數組長度 +1,將給定對象放在最后的位置,set 方法是替換指定索引位置的元素,get 方法則是獲取指定索引位置的元素。
6)remove 方法
刪除指定索引位置的元素或者指定元素,不推薦使用,對數組操作比較復雜,如果你使用了此方法,說明你應該考慮用 LinkedList 了。
3、最佳使用建議
1)ArrayList 是 Array 的復雜版本
ArrayList 內部封裝了一個 Object 類型的數組,從一般的意義來說,它和數組沒有本質的差別,甚至于 ArrayList 的許多方法,如 Index、IndexOf、Contains、Sort 等都是在內部數組的基礎上直接調用 Array 的對應方法。
2)內部的 Object 類型的影響
對于一般引用類型來說,這部分的影響不大,但是對于值類型,往 ArrayList 里面添加和修改元素,都會引起裝箱和拆箱操作,頻繁的操作可能會影響一部分效率。
3)數組擴容
這是對 ArrayList 效率影響比較大的一個因素。?
每當執行 Add、AddRange、Insert、InsertRange 等添加元素的方法,都會檢查內部數組的容量是否不夠了,如果是,它就會以當前容量的兩倍來重新構建一個數組,將舊元素 Copy 到新數組中,然后丟棄舊數組,在這個臨界點的擴容操作,應該來說是比較影響效率的。?
例 1:比如,一個可能有 200 個元素的數據動態添加到一個以默認 16 個元素大小創建的 ArrayList 中,將會經過:?
16*2*2*2*2 = 256?
四次的擴容才會滿足最終的要求,那么如果一開始就以?ArrayList list = new ArrayList(210)?的方式創建 ArrayList,不僅會減少 4 次數組創建和 Copy 的操作,還會減少內存使用。
例 2:預計有 30 個元素而創建了一個 ArrayList:?
ArrayList List = new ArrayList(30);?
在執行過程中,加入了 31 個元素,那么數組會擴充到 60 個元素的大小,而這時候不會有新的元素再增加進來,而且有沒有調用 TrimSize 方法,那么就有 1 次擴容的操作,并且浪費了 29 個元素大小的空間。如果這時候,用?ArrayList list = new ArrayList(40)?那么一切都解決了。?
所以說,正確的預估可能的元素,并且在適當的時候調用 TrimSize 方法是提高 ArrayList 使用效率的重要途徑。?
特別感謝:
1、Java 中 ArrayList 類的用法
2、《Thinking In Java》
3、《Core Java Volume I》
轉載于:https://www.cnblogs.com/JavaSubin/p/5539430.html
總結
以上是生活随笔為你收集整理的Java 集合框架(二)—— ArrayList的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 元气骑士法师成就皮肤怎么获得?
- 下一篇: 挥一挥手是什么歌啊