Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 谷歌番石榴库中newArrayList(E…元素)的好奇心_Java_Collections_Guava - Fatal编程技术网

Java 谷歌番石榴库中newArrayList(E…元素)的好奇心

Java 谷歌番石榴库中newArrayList(E…元素)的好奇心,java,collections,guava,Java,Collections,Guava,此代码是guava库的简单代码 为了便于阅读,我对原始代码进行了简化,请参见=> //案例A 公共静态ArrayList newArrayList(E…元素){ int capacity=computeArrayListCapacity(elements.length); ArrayList=新的ArrayList(容量); Collections.addAll(列表、元素); 退货清单; } 静态int-computeArrayListCapacity(int-arraySize){ 长值=5

此代码是guava库的简单代码

为了便于阅读,我对原始代码进行了简化,请参见=>

//案例A
公共静态ArrayList newArrayList(E…元素){
int capacity=computeArrayListCapacity(elements.length);
ArrayList=新的ArrayList(容量);
Collections.addAll(列表、元素);
退货清单;
}
静态int-computeArrayListCapacity(int-arraySize){
长值=5L+arraySize+(arraySize/10);
如果(值>整数.最大值){
返回Integer.MAX_值;
}
if(值<整数最小值){
返回Integer.MIN_值;
}
返回(int)值;
}
为什么将容量设置为5L+arraySize+(arraySize/10)

三种情况(A、B、C)有什么不同

//案例B
公共静态ArrayList newArrayList(E…元素){
ArrayList=新的ArrayList(elements.length);
Collections.addAll(列表、元素);
退货清单;
}
//案例C
公共静态ArrayList newArrayList(E…元素){
ArrayList=新建ArrayList();
Collections.addAll(列表、元素);
退货清单;
}

马蒂亚斯的评论没有什么可补充的:

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

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


案例C首先分配一个包含10个元素的数组,然后可以在
集合中多次替换这些元素。IIUIC对
元素发生两次。长度==16
(即
10->15->22
,因为ArrayList的增长因子是1.5)。

它创建了一个新的ArrayList,它有一点额外的容量。由于列表通常在具有动态计数的数据时使用,这样做的好处是添加下一个元素时,列表不需要昂贵的调整大小(案例b)。调整大小的代价很高,因为它是通过创建一个新的(更大的)数组并将所有现有元素复制到该新数组中来完成的。您对
Integer.MIN_VALUE
的质疑有误导性,我建议将其删除(无论如何,这并不准确,因为
saturatedCast
从来不会同时进行这两项测试。@maaartinus是的,我没有使用computeArrayListCapacity方法。它只是guava-Ints.java.This中的代码。你可以看到
5L+arraySize+(arraySize/10)
有一个“
任务:找出正确的行为,并记录它
”旁边的注释基本上意味着这个表达式没有经过严格的研究。它的意思是允许在列表中添加一些内容,而且很可能是经验的(随机的)。这里的
5
用于小列表(长度
length
大约为10,因为它们不会从
length/10
中得到任何东西),对于大列表,
length/10
(成百上千的
length
,因为对他们来说,5算不了什么)。同意所有的观点。我还想补充一点,没有理由不使用
arraySize>>3而不是除法来节省大约40个周期(或者可能
排列>>4
,1/8和1/16都接近1/10)。
// 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;
}
//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;
}