2017-08-02 80 views
-2

我有一个列表< ArrayList <字符串> >对象在Java中。内部ArrayList <字符串>具有恒定的大小。以最少内存消耗Resuse ArrayList

因此,在填充List时,我使用以下逻辑。

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>(); 
ArrayList<String> list = new ArrayList<String>(); 
for(i = 0; i < 10; i++) { 
    .... 
    for(j = 0; j < 10; j++) { 
     list.add(/* some string */); 
    } 
    map.add(list); 
    list.clear(); 
} 

地图中的每个列表都填充了空值。 另外,每个回路单独实例列表,解决了我的问题,如:

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>(); 
ArrayList<String> list = new ArrayList<String>(); 
for(i = 0; i < 10; i++) { 
    .... 
    list = new ArrayList<String>(); 
    for(j = 0; j < 10; j++) { 
     list.add(/* some string */); 
    } 
    map.add(list); 
    //list.clear(); 
} 

我具有约100,000的ArrayList需要被存储在列表对象中的数据集,我不希望实例ArrayList每次,因为内存开销。

所以,除了单独实例吧,我想多了一个办法:

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>(); 
ArrayList<String> list = new ArrayList<String>(); 
for(i = 0; i < 10; i++) { 
    .... 
    for(j = 0; j < 10; j++) { 
     list.add(/* some string */); 
    } 
    map.add(new ArrayList<String>(list)); 
    list.clear(); 
} 

哪个这些方法会给我至少内存消耗(性能不是优先考虑)? 如果不是这些,是否有另一种方式可以更有效地完成此操作?

+0

对不起,我没有注意到你在做'新的ArrayList (列表)' - 这不会增加更多的工作吗?然后你需要清除 –

+0

除了如果我不这样做,添加到地图对象中的列表也被清除为空值。在清除它之前,我需要改变列表的引用,唯一的方法就是实例化它。 – Penman

+0

所以代码块2不需要做'清除' –

回答

3

如果你关心内存消耗,你可以做的最好的事情就是当你完成列表填写时,打电话给trimToSize()。这将删除其中的空容量(并且如果添加元素,则需要调整大小)。

你仍然需要使用不同的列表,所以第二种方式是任何理智的程序员会做的。

由于 内存开销,我不想每次都实例化ArrayList。

没有记忆开销。你正在使用内存,因为你需要。如果你想拥有大约100,000个列表,你将不得不创建大约100,000个列表,结尾。

0

都没有。和两者。 Java是一种垃圾收集语言。内存消耗具有由JVM配置设置的严格上限。

+0

这两者都不是什么意思? – Penman

1

不要忘记你存储指向列表中的对象的指针。而不是目标本身。

ArrayList<String> list = new ArrayList<String>(); 
for(i = 0; i < 10; i++) { 
    .... 
    for(j = 0; j < 10; j++) { 
     list.add(/* some string */); 
    } 
    map.add(list); 
    list.clear(); 
} 

您存储列表中的地图对象,那么你在列表中删除所有内容。在地图的列表不是您的名单的副本!最后,地图将包含10次相同的空列表。

在java中,数组列表大小将是一个指针(64位)+'数组大小'指针的内容+一些字节的东西。 “阵列大小”不是内容大小。 消耗较少,您可以将数组大小设置为内容大小。

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>(10); 
for(i = 0; i < 10; i++) { 
    .... 
    ArrayList<String> list = new ArrayList<String>(10); 
    for(j = 0; j < 10; j++) { 
     list.add(/* some string */); 
    } 
    map.add(list); 
} 

无论如何,通常列表大小与内容大小无关。

+0

您建议的代码块和我的代码块2的内存效率会不同? – Penman

+0

我的最后一个代码块使arraylist内部大小匹配它将有的实际大小。所以,如果您将容量设为自动容量(10号容量,我不记得容量是12还是16容量),那么您的内存会少一点,所以yeahhhh!很好,你有每个列表16bytes到54bytes的差异。 – wargre