よくある疑問が生じます: リストを初期化するにはどうすればよいですか? 以下のコードは機能しません:コンパイル エラーが発生します: ローカル変数名が 初期化されていない可能性があります。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