Java の ArrayList の初期容量が 10 である理由は何ですか?
HashMap の初期容量が 16 なのはなぜですか?
ArrayList の初期化能力について話すときは、まず HashMap の初期化能力を確認する必要があります。 Java 8 のソース コードを例として示します。HashMap には、初期化容量と読み込み係数の 2 つの関連要素があります。
/** * The default initial capacity - MUST be a power of two. */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 /** * The load factor used when none specified in constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f;
HashMap では、配列のデフォルトの初期化容量は 16 です。データがいっぱいになると、デフォルト容量の0.75までの場合、2倍に拡張されます。もちろん、ユーザーは初期化中に指定されたサイズを渡すこともできます。ただし、2 の n 乗の値を使用するのが最適であることに注意してください。2 の n 乗に設定されていない場合、HashMap も変換しますが、もう 1 つの手順が必要になります。
HashMap の実装原理については、インターネット上にすでにたくさんの記事があるため、ここでは詳しく説明しません。知っておく必要があることの 1 つは、キー値の座標を計算する HashMap のアルゴリズムです。つまり、キー値をハッシュして配列内の座標にマッピングします。
このとき、HashMapの容量を2のn乗にすることで、ハッシュ演算時に10進数に変換せずにビット演算でメモリを直接操作できるため効率が高くなります。
一般に、HashMap が 2 の n 乗を使用し、デフォルト値が 16 である理由は、 以下の考慮事項があると考えられます。 ハッシュの衝突を減らす;
マップ クエリの効率を向上させる;
##割り当てが小さすぎるため、頻繁な拡張を防ぐ;- 過剰な割り当てはリソースを無駄にします;
- つまり、HashMap がデフォルト値として 16 を使用する理由は、ハッシュの衝突を減らし、効率を向上させるためです。
ArrayList の初期容量は 10 ですか?
次に、ArrayList の初期容量が 10 であるかどうかを確認し、なぜこの値になるのかを説明します。
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10;
明らかに、デフォルトのコンテナ初期化値は 10 です。また、JDK1.2 から JDK1.6 まで、この値は常に 10 です。
JDK1.7 以降、ArrayList を初期化するとき、デフォルト値は空の配列に初期化されます。
/** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
ここにはデフォルト値が正しいという友人がいるはずです。 Java 8 の ArrayList の初期サイズは 10 ではなく 0 です。また、コンストラクター メソッドのコメントにも奇妙な点があることがわかります。初期容量 10 の空のリストを構築します。なんてこった?明らかに空いてますよ!
疑問は捨てて、まず ArrayList の add メソッドを見てみましょう:
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
ansureCapacityInternal メソッドが add メソッドで呼び出されます。このメソッドを入力すると、最初は空のコンテナーであるため、
size=0Incoming minCapacity=1:
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }
上記のメソッドでは、まず、calculateCapacity によって容量が計算されます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'> private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
は、minCapacity
が 10 (
) に再割り当てされていることを検出し、
ensureExplicitCapacity(minCapacity);ThisminCapacity を渡します。 =10
,以下はメソッド本体です:
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'> private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
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);
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
上記のコードのgrowメソッドは拡張を処理するために使用され、容量を1.5に拡張します。元のサイズの 2 倍になります。
上記の処理フローを理解すると、ArrayList の初期容量は基本的に 10 のままですが、遅延ロードが使用されているだけであることがわかります。これは、メモリを節約するために Java 8 によって実行される最適化です。したがって、最初から最後まで、ArrayList の初期容量は 10 です。 遅延読み込みの利点をもう 1 つ挙げておきます。プログラム内に数千の ArrayList がある場合、デフォルト サイズの 10 オブジェクトは、作成時に基になる配列に 10 個のポインタ (40 または 80) が割り当てられることを意味します。バイト) を作成し、それらを null 値で埋めると、(null 値で埋められた) 空の配列は多くのメモリを占有します。配列を遅延初期化できれば、メモリ領域を大幅に節約できます。 Java 8 での変更は上記の目的のためです。
ArrayList の初期容量が 10 なのはなぜですか?
最後に、ArrayList の初期容量が 10 である理由について説明します。実際、理由はなく、大きすぎず、小さすぎず、目にちょうど良い「感じ」であると言えます。
まず、HashMap について説明するときに、HashMap が 2 の n 乗を選択する理由は、ハッシュ アルゴリズムのパフォーマンスと衝突を考慮するためであると述べました。この問題は ArrayList には存在しません。 ArrayList は、アルゴリズム レベルでの最適化を考慮せず、単純に拡張する配列です。一定の値を超えると成長する可能性があります。したがって、理論的に言えば、ArrayList の容量は任意の正の値にすることができます。
ArrayList のドキュメントには、10 が選択された理由が説明されていませんが、おそらくパフォーマンスの損失とスペースの損失の間の最適な一致を考慮したためだと思われます。 10. 大きすぎず、小さすぎず、メモリスペースを無駄にせず、パフォーマンスもそれほど低下させません。
そもそもなぜ 10 が選ばれたのかを尋ねる必要がある場合は、このコードの作成者「Josh Bloch」に尋ねる必要があるかもしれません。
注意深く観察すると、他にもいくつかの興味深い初期化容量の数値が見つかるでしょう:ArrayList-10 Vector-10 HashSet-16 HashMap-16 HashTable-11
ArrayList の初期化容量は Vector の初期化容量と同じです。 10; HashSet と HashMap の初期化容量は同じで 16; HashTable は 11 だけを使用しますが、これも非常に興味深い質問です。
以上がJava の ArrayList の初期容量が 10 である理由は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4
