重新使用内存消耗最少的ArrayList

时间:2017-08-02 07:11:57

标签: java list arraylist out-of-memory

我有一个List< ArrayList< String>> Java中的对象。内部ArrayList< String>是一个不变的大小。

因此,在填充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个ArrayLists的数据集,需要存储在List对象中,并且我不想每次都实例化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();
}

这些方法中的哪一种会给我最少的内存消耗(性能不是优先考虑的因素)? 如果不是这些,是否有另一种方法可以更有效地完成这项工作?

3 个答案:

答案 0 :(得分:3)

如果您关心内存消耗,那么当您填写完列表时,您可以做的最好就是致电trimToSize()。这将删除其中的空容量(如果添加元素,则需要调整大小)。

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

  

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

没有内存开销。您需要使用内存。如果你想拥有~100,000个列表,你将需要创建~100,000个列表,故事结束。

答案 1 :(得分: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();
}

您将列表存储为地图对象,然后删除列表中的所有内容。 地图中的列表不是您的列表的副本!最后,map将包含相同空列表的10倍。

在java中,数组列表大小将是一个指针(64位)+&#39; arraysize&#39;内容的指针+东西的一些字节。 &#39; ARRAYSIZE&#39;不是内容大小。 为了减少消耗,您可以将arraysize设置为内容大小。

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);
}

无论如何,与内容大小相比,通常列表大小都没有。

答案 2 :(得分:0)

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