Javaコレクションごとにデフォルトの容量が異なるのはなぜですか?


11

さまざまなコレクションコンストラクターを見ると、疑問が浮かびます。ArrayList()が初期容量10の空のリストを作成し、ArrayDeque()が16要素を保持するのに十分な初期容量の空の配列dequeを作成するのはなぜですか。


私は新しい容量に容量制限がありませんでした。add()で新しい要素を追加するだけです。常に機能します。
Tulainsコルドバ

1
彼はArrayList実装内の配列の初期配列サイズについて話していると思います。その名前が示すように、ArrayListはカバーの下にある単なる古い配列であり、現在の配列サイズに含まれるよりも多くの要素を追加しようとすると、より大きな配列が自動的に作成されます。
dsw88

1
StringBuilderはデフォルトの容量を持っているもう1つのものだと思います、それは10ですか16ですか?
インゴ

@Ingo興味深い。私は、コレクションの外にあるものが容量にめちゃくちゃであることさえ知らなかったが、それは理にかなっていると思う。当時は容量のタグがなかったので、他の用途にあまり興味を持っていませんでした。
オールドバッドマングレイ

回答:


17

短い答え

ArrayDequeの容量は2の累乗でなければならず、16は2の最小の累乗であり、少なくとも10です。


ArrayDequeは、多くの%演算をどこでも使用して、円形のふりをする線形配列をラップする必要があります。

a % b2の累乗であるa & (b - 1) かの ように表現できますb。ビット単位のANDは非常に高速であるため、ArrayDequeの容量は2のべき乗に制限されています。実装では、すべての操作が実際のビットマスクではなくビットマスクで実行されます。

これはまた、新しいHashMapが素数テーブルサイズではなく2の累乗を使用しない理由でもあります。これも、%演算を頻繁にビット単位で実行する必要があり、はるかに高速であるためです。

したがって、ベースラインが10の場合、2のべき乗の制限がある構造体は、最小の2のべき乗である少なくとも10であるため、16を使用する必要があります。


3

特定の理由がない可能性を排除しないでください。

これらの2つのコレクションは、異なるチームによって作成された可能性があります。どちらもデフォルトのキャパシティとして小さな数を選択しましたが、最初のチームは10進数で考えて10を選択し、2番目のチームはバイナリで16を選択しました。


1

@Esailijaの答えは、この特定のケースに適しています。

ただし、より一般的には、多くの要因に依存するトレードオフです。いくつか例を挙げます。

  • データ構造は通常どのように使用されますか?データバッファとして使用されるデータ構造は、通常、たとえば小さなタプルに使用されるデータ構造よりもはるかに高い容量を好むでしょう。
  • ターゲットCPUプラットフォームのキャッシュラインに収まるデフォルトのデータサイズは?デフォルトがキャッシュラインに収まる場合、パフォーマンスに大きな違いをもたらす可能性があります。Javaのデフォルトとして10を選択するのは、10個の32ビットワードの配列と配列/オブジェクトのオーバーヘッドが64バイトキャッシュラインに収まるためです。
  • スペースとランタイムの効率をどの程度重視していますか?実行時のパフォーマンスを向上させたい場合は、後で余分な再割り当てを避けるために、通常はより多くのスペースを事前に割り当てることをお勧めします。

これらのトレードオフの結果、コレクションの実装ごとに最適なデフォルト容量が異なる可能性があることは十分に理解できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.