JavaRush /Java Blog /Random-JA /new ArrayList(????) どこでどのように初期化するのが良いですか
Vovan
レベル 22

new ArrayList(????) どこでどのように初期化するのが良いですか

Random-JA グループに公開済み
コレクション フレームワーク を使用せずにコードを記述するのは、とんでもないことです。これは、多くの優れたソリューションを備えた素晴らしい Java です。さらに重要なのは、配列とは異なり、サイズを心配する必要がないことです。ArrayList はメモリがなくなるまで増大します。開発者は、初期サイズやArrayIndexOutOfBoundsExceptionエラーについて心配する必要はありません。しかし、メモリ量を監視する条件がある場合はどうなるでしょうか? コレクションを操作するときにメモリを効率的に使用できますか?
よくある疑問が生じます: リストを初期化するにはどうすればよいですか? 以下のコードは機能しません:コンパイル エラーが発生します: ローカル変数名が 初期化されていない可能性があります。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 など。
要素が 100 個の場合、 JVM は新しい配列を数回作成し、そこに要素をコピーする必要があります。このことを考慮すると、必要な配列サイズの想定がある場合は、初期容量をそれに近い値に設定することが望ましいと考えられます。行動のためのガイドラインをいくつか示します。
  1. 必要な場合にのみコレクションを作成し、そうでない場合は null に初期化するか、Collections.EMPTY_LISTを使用します。
  2. 必要な正確なサイズがわかっている場合は、コレクション コンストラクターでそれを指定します。
  3. 要素の数が 10 を超えないことが確実な場合は、デフォルトのコンストラクターを自由に使用してください。
  4. サイズがゼロのコレクションの作成に伴うリスクは、新しい配列の作成とデータのコピーの頻度が高くなる可能性があることです。サイズがゼロのコレクションを使用する利点が本当に大きいかどうかをよく考える必要があります。
  5. メソッドの先頭で大きすぎるコレクションを初期化し、それを減らしたい場合は、trimToSize()メソッドがあります。
もちろん、これらのガイドラインは配列ベースのコレクションを操作する場合に適用されますが、リンク リストの場合はどれも意味がありません。実際、これらの問題がプログラムの致命的となる可能性は低いですが、もう少し改善する機会があるのであれば、それを使用してみてはいかがでしょうか。他に役立つヒントはありますか? 物事をより良くする方法を見つけましたか? それとも、これはすべて不要なのでしょうか?どう思いますか?
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION