31

リスト ( List<T> list) があり、マップ ( ) を使用して ID でそのオブジェクトにインデックスを付けたいと考えていますHashMap<Integer, T> map。以下のコードのように、コンストラクターの初期容量list.size()として常に使用します。この場合、これは使用するのに最適な初期容量ですか?HashMap

: これ以上アイテムをマップに追加することはありません。

List<T> list = myList;
Map<Integer, T> map = new HashMap<Integer, T>(list.size());
for(T item : list) {
    map.put(item.getId(), item);
}
4

6 に答える 6

15

Guava'sは、このヘルパー メソッドを使用して、予想される値の数に基づいてMaps.newHashMapWithExpectedSize、デフォルトの負荷係数 の初期容量を計算します。0.75

/**
 * Returns a capacity that is sufficient to keep the map from being resized as
 * long as it grows no larger than expectedSize and the load factor is >= its
 * default (0.75).
 */
static int capacity(int expectedSize) {
    if (expectedSize < 3) {
        checkArgument(expectedSize >= 0);
        return expectedSize + 1;
    }
    if (expectedSize < Ints.MAX_POWER_OF_TWO) {
        return expectedSize + expectedSize / 3;
    }
    return Integer.MAX_VALUE; // any large value
}

参考:ソース

newHashMapWithExpectedSizeドキュメントから:

成長することなく要素を保持するHashMapのに十分な「初期容量」を持つインスタンスを作成します。この動作は広く保証することはできませんが、OpenJDK 1.6 では正しいことが確認されています。また、メソッドが返されたマップを誤ってオーバーサイズしていないことも保証できません。expectedSize

于 2013-04-05T21:46:14.713 に答える
13

あなたがしていることは問題ありません。このようにして、ハッシュ マップに少なくとも初期値に対して十分な容量があることを確認します。ハッシュ マップの使用パターンに関する詳細な情報がある場合 (例: 頻繁に更新されますか? 多くの新しい要素が頻繁に追加されますか?)、より大きな初期容量 (たとえば、list.size() * 2) を設定することをお勧めしますが、決してそれ以下にはしないでください。プロファイラーを使用して、初期容量がすぐに不足しているかどうかを判断します。

アップデート

(int)Math.ceil(list.size() / loadFactor)初期サイズ変更を回避するために、初期容量を (通常、デフォルトの負荷係数は 0.75) に設定する必要があることを提案してくれた @PaulBellora に感謝します。

于 2013-04-05T21:41:46.163 に答える