ArrayList と HashMap の遅延初期化(7u40)

小ネタです。

Java 7u40 で空の ArrayList と HashMap のインスタンス生成が最適化されました。

Bug ID: JDK-8011200 (coll) Optimize empty ArrayList and HashMap

ArrayList の初期化

今までは、

new ArrayList<>();

とした時点で、以下のように初期容量10のオブジェクト配列が割り当てられていました。

    public ArrayList() {
        this(10);
    }

    public ArrayList(int initialCapacity) {
        super();
        // ・・・
        this.elementData = new Object[initialCapacity];
    }


7u40 からは、以下のように共有の空配列が割り当てられるようになっています。

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

HashMap の初期化

HashMapでも同じように要素数16の Entry が割当られていましたが、

    transient Entry[] table;
    static final int DEFAULT_INITIAL_CAPACITY = 16;
    
    public HashMap() {
        // ・・・
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }


空のEntryを割り当てるように変更されています。

    static final Entry<?,?>[] EMPTY_TABLE = {};
    transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;

    public HashMap() {
        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
    }


Java8 では内部の管理テーブルが Node に変更になっていたりもします。

    transient Node<K,V>[] table;

    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
    }

遅延初期化

いずれの場合も、add や put などで必要になった時にデフォルトの容量で確保されます。