4

タイトルにあるように、初期容量が 500 の ArrayList を作成し、しばらくしてからクリアすると、その容量は 500 のままになりますか? または、そのために再初期化する必要がありますか?

4

3 に答える 3

5

はい、容量は維持されます。(少なくとも、Oracle VM の実装ではありません):

/**
 * Removes all of the elements from this list.  The list will
 * be empty after this call returns.
 */
public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

明確にするために: anArrayListは配列 (たとえば、ArrayList の int[]) によってサポートされており、新しい配列を作成してコピーすることで容量を超えると、その配列が拡張されます。クリアしても (コードに見られるように) 新しい小さな配列が作成されたり、そこにコピーされたり、古い大きな配列が破棄されたりすることはありません。

于 2012-11-27T10:16:48.437 に答える
2

いいえ、リストから要素を削除しても、arrayList の容量は変更されません。ただし、 trimToSizeを使用して自分で行うことができます。

通常、要素を追加すると容量が増加するため、容量を気にする必要はありません。容量を心配する理由として考えられるのは、頻繁な再割り当てによるパフォーマンスです。それ以外の場合は、容量の再初期化について心配する必要はありません。

于 2012-11-27T10:22:24.270 に答える
1

ArrayListのCapacityの助けを借りて、容量がリセットされていないことがわかりました。サンプルコードを見つける:

import java.lang.reflect.Field;
import java.util.ArrayList;
public class Main {

    public static void main(String[] args) {
        try {
            ArrayList<Object> al = new ArrayList<Object>(500);
            System.out.println(getCapacity(al));
            for (int i = 0; i < 550; i++) {
                al.add(new Object());
            }
            System.out.println(getCapacity(al));
            al.clear();
            System.out.println(getCapacity(al));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    static int getCapacity(ArrayList<?> l) throws Exception {
        Field dataField = ArrayList.class.getDeclaredField("elementData");
        dataField.setAccessible(true);
        return ((Object[]) dataField.get(l)).length;
    }
}
于 2012-11-27T10:44:03.667 に答える