出現了一個標準問題:如何初始化列表?下面的程式碼將不起作用:它將導致編譯錯誤: 局部變數名稱可能尚未 初始化。Java 規格要求所有局部變數(存在於堆疊中的變數)都使用適當的值進行初始化。您可以這樣做:毫無疑問,清單必須被初始化。您可以在第一行建立列表,也可以做一些更聰明的事情並使用延遲 初始化,就像我們在 getAllNames()方法中所做的那樣。在這種情況下,清單只會在必要時建立 - 如果不滿足初始條件,清單將永遠不會出現在堆上。這裡我們來到了主要問題: 我們應該為列表設定什麼大小?最好的選擇是給他準確的尺寸。例如:在這種情況下,必須傳回 n 個名稱,因此會建立一個包含 n 個元素的集合。 然而, n的確切值並不總是已知。即使在給出的範例中,如果 n=1000並且只有 100 個可用名稱怎麼辦?使用集合時,最流行的方法是呼叫預設建構函式。如果您查看 Java 原始碼(版本 1.6),您會看到, 預設會建立一個包含 10 個元素的清單。也就是說,當我們不打算在清單中儲存超過 10 個元素時,我們可以安全地使用預設建構子。如果您嘗試新增第 11 個元素會發生什麼?好吧,沒什麼不好...元素將被成功添加。看方法: 陣列的大小是由 ensureCapacity方法控制的。 尺寸增加1.5倍。建立一個新數組並將元素移入其中。如果我們將大小設為 10,則在第 11 個元素上:
public List
getAllNames() { List
names; if (/*необходимые условия выполнены*/) { names = new ArrayList
(); /*заполнение списка*/ } return names; }
List
names = null; List
names = new ArrayList
(); List
names = new ArrayList
(0); List
names = new ArrayList
(size);
public List
getTopNames (int n) { List
names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList
(n); /*заполнение списка*/ } return names; }
names = new ArrayList
();
/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; }
public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
- 大小改為 10 * 3 / 2 + 1 = 16
- 下次增加 = 16 * 3 / 2 + 1 = 25
- 下次增加 = 25 * 3 / 2 + 1 = 39 等等。
- 僅在需要時建立集合,否則將其初始化為 null 或使用Collections.EMPTY_LIST。
- 如果您知道所需的確切大小,請在集合建構函式中指定它。
- 如果您確定元素數量不會超過 10,請隨意使用預設建構函數。
- 與創建零大小集合相關的風險是創建新數組和複製資料的頻率可能會更高。您需要非常仔細地考慮使用大小為零的集合是否有很多好處。
- 如果你在方法開始時初始化的集合太大並且想要減少它,可以使用trimToSize()方法。
GO TO FULL VERSION