4

这段代码是番石榴库的简单代码。

为了便于阅读,我做了简化,原始代码见 =>链接

// Case A
public static <E> ArrayList<E> newArrayList(E... elements) {
    int capacity = computeArrayListCapacity(elements.length);
    ArrayList<E> list = new ArrayList<E>(capacity);
    Collections.addAll(list, elements);
    return list;
}

static int computeArrayListCapacity(int arraySize) {
    long value = 5L + arraySize + (arraySize / 10);
    if (value > Integer.MAX_VALUE) {
        return Integer.MAX_VALUE;
    }
    if (value < Integer.MIN_VALUE) {
        return Integer.MIN_VALUE;
    }
    return (int) value;
}

为什么将容量设置为5L + arraySize + (arraySize / 10)

3种情况(A,B,C)有什么不同?

//Case B
public static <E> ArrayList<E> newArrayList(E... elements) {
    ArrayList<E> list = new ArrayList<E>(elements.length);
    Collections.addAll(list, elements);
    return list;
}

//Case C
public static <E> ArrayList<E> newArrayList(E... elements) {
    ArrayList<E> list = new ArrayList<E>();
    Collections.addAll(list, elements);
    return list;
}
4

1 回答 1

3

Matthias 的评论没有什么可补充的:

当列表稍后增长时,情况 A 是最佳的,但不会太多:小于 10% 加上 5 个以上的元素。如果它永远不会增长,那么你就是在浪费一些内存。如果它增长得更多,就会发生一些调整大小,但总的来说,任何人都无能为力。

在列表没有增长的不可能的情况下,案例 B 是最佳的。但这是不可能的,因为通常ImmutableList可以使用 。

案例 C 首先分配一个包含 10 个元素的数组,然后可以在Collections.addAll. IUIIC 它发生了两次elements.length==16(即10 -> 15 -> 22因为 ArrayList 的增长因子是 1.5)。

于 2013-09-26T08:26:08.233 回答