浅谈guava包下wArrayListWithExpectedSize()的使
⽤
⽬前app的代码中不少使⽤wArrayListWithExpectedSize(), 针对此⽅法的使⽤是否规范做了⼀些分析
1. 关于 wHashMapWithExpectedSize()
看到wArrayListWithExpectedSize()此⽅法, 想必你定会想到HashMap的wHashMapWithExpectedSize()⽅法,
我们知道HashMap的默认加载因⼦是0.75, HashMap在put新数据时, 会计算当前元素个数是否超过当前容量的0.75倍, 若达到则扩容。
在初始化HashMap时, 若使⽤者已知道具体的元素个数, 则初始化的HashMap的容量应该是
初始容量 = 元素个数/0.75 + 1
学士学位查询
notation我们来看下源码:
static int capacity(int expectedSize) {
if (expectedSize < 3) {
checkNonnegative(expectedSize, "expectedSize");
return expectedSize + 1;迪士尼英语怎么样
}
if (expectedSize < Ints.MAX_POWER_OF_TWO) {
// This is the calculation ud in JDK8 to resize when a putAll
// happens; it ems to be the most conrvative calculation we
// can make. 0.75 is the default load factor.
return (int) ((float) expectedSize / 0.75F + 1.0F);
}
return Integer.MAX_VALUE; // any large value
}
2. ArrayList的扩容机制
private void ensureExplicitCapacity(int minCapacity) {故障检测
modCount++;
//minCapacity为add后的元素个数
if (minCapacity - elementData.length > 0) {
//扩容操作
grow(minCapacity);
}
}
通过源码可见ArrayList的扩容机制与HashMap并不⼀样, ArrayList的在执⾏add⽅法时, 只有新增元素后的总长度⼤于容量时才进⾏扩容,否则不扩容
paragon具体扩容步骤如下
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually clo to size, so this is a win:
elementData = pyOf(elementData, newCapacity);
大量英文}
通过上述源码可以看到, ArrayList进⾏扩容时, 先进性⼀次扩容, 扩容后的容量⼤⼩为
oldCapacity + oldCapacity >>1
即原容量的1.5倍, 若当前元素个数(minCapacity) 还⼤于扩容后容量, 则取minCapacity为最新容量⼤⼩, 然后进⾏数据copy
圣经在线阅读有声朗读3. wArrayListWithExpectedSize()的实现
static int computeArrayListCapacity(int arraySize) {
checkNonnegative(arraySize, "arraySize");
return Ints.saturatedCast(5L + arraySize + (arraySize / 10));
}
源码可以看出, newArrayListWithExpectedSize()⽅法对ArrayList的初始化容量的计算是
最终容量 = 5+预期值+ 预期值/10
若你要使⽤⼀个长度为100的集合, 使⽤该⽅法会初始化⼀个容量为 5+100+10=115的集合
看⼀下此⽅法的注释:
This method will soon be deprecated. Even in the rare ca
* that you do want some amount of padding, it's best if you choo your
* desired amount explicitly.
商务英语专业描述
这种⽅法很快就会被弃⽤。即使在罕见的情况下
*你需要⼀些填充物,最好选择
*明确要求的数量。
注释中说明 构建ArrayList时最好直接传⼊元素, 或者明确你要的容器数量
对参数的解释为:
an estimate of the eventual {@link List#size()}
对新列表的最终长度的估计值
也就是说, 当前⽅法是使⽤者不确定集合元素个数时, 但是有个预估值时去使⽤。
4. ⽬前代码中使⽤是否规范
⽬前代码中不少地⽅创建ArrayList是为了将⼀个实体类集合成为⼀个DTO集合的转换。也就是说是为了创建⼀个明确元素数量的ArrayList, 使⽤wArrayListWithExpectedSize() 则初始化的集合容量⾄少多出5, 造成了不必要的内存浪费
例如:
private List<ActivityInfoBo> getActiveBoList(List<Integer> activityIdList) {
List<ActivityInfoBo> activeList = wArrayListWithExpectedSize(activityIdList.size());
for (Integer activityId : activityIdList) {
ActivityInfoBo activityInfoBo = BrandWeekActivityBean()
.getActivityInfoByActivityId(activityId);
activeList.add(activityInfoBo);
}
return activeList;
}
当明确集合元素个数时, 初始化ArrayList可以使⽤ArrayList⾃带的构造函数
new ArrayList<>(n) n为集合长度值
或者使⽤wArrayListWithCapacity()⽅法, 此⽅法也是直接使⽤了ArrayList的构造public static <E> ArrayList<E> newArrayListWithCapacity(int initialArraySize) { checkNonnegative(initialArraySize, "initialArraySize"); // for GWT.
inner
return new ArrayList<E>(initialArraySize);
}苏州翻译