Java ArrayList添加当前大小以外的项目

时间:2012-01-19 11:18:22

标签: java arraylist

想知道是否有一种有效的方法将项目添加到Java的ArrayList中,其位置比当前大小更大:

情景:

   ArrayList<Item> items = new ArrayList<Item>;
   ... let's say I add three elements

现在我想在位置10添加一个项目(将项目从3到10保留为空)

  items.add(10,newItem);  // item.size() == 3 

是否有一种有效的方法可以使用空值调整/填充ArrayList?

Java的实现使大小字段变为私有: - (..

10 个答案:

答案 0 :(得分:6)

imho你可以做的最好的事情是items.addAll(Collections.nCopies(6, null))并希望,ArrayList实现了一些内部紧固的行为

答案 1 :(得分:2)

这个怎么样?

ArrayList<Item> items = new ArrayList<Item>();

items.add(new Item(0));
items.add(new Item(1));
items.add(new Item(2));

items.addAll(Collections.<Item>nCopies(7, null));
items.add(10,new Item(10));

System.out.println(items);

打印

[0, 1, 2, null, null, null, null, null, null, null, 10]

答案 2 :(得分:1)

改为使用TreeMap。这是检查和谐消耗的简单例子。分别运行第一个和第二个测试并使用jvisualvm检查堆大小。请记住多次执行GC。

    public class Test {


            public static void main(String[] args) throws InterruptedException {
                String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque metus.";


                //Test 1
                ArrayList<String> l = new ArrayList<String>();

                for (int i = 0; i < 1000000; i++) {
                    l.add(s + " " + i);
                    l.addAll(Collections.nCopies(i % 10, (String)null)); //Add some nulls
                }
                //Heap is > 5MB

                //Test 2 uncomment and comment test 1
    //          SortedMap<Integer, String> map = new TreeMap<Integer, String>();
    //          for (int i = 0; i < 1000000; i++) {
    //              map.put(i,s + " " + i);
    //          }
                //Heap is < 5MB

                Thread.sleep(100000);

            }
    }

看起来TreeMap版本的内存消耗比ArrayList版本更少。检查一下自己。

答案 3 :(得分:1)

这是一个较旧的问题,但是您现在可以使用SparseArray(几乎)直接替代ArrayList。它允许不连续的整数键值,如果尚未为键设置值,则返回null。在性能方面,它是根据您的需求确切设计的。您可以使用add来代替append,它更具描述性,因为您可以将max键的末尾追加到末尾,即使有间隙也是如此。您也可以set设置为任意键值,即使该键值超出最大键值。

答案 4 :(得分:0)

不,你不能:

http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#add(int,E)

  

抛出:IndexOutOfBoundsException - 如果索引超出范围   (index&lt; 0 || index&gt; size())

答案 5 :(得分:0)

我会考虑在这里使用SortedMap而不是列表。这将允许索引不存在:

SorteMap<Integer, Item> myMap = new TreeMap<Integer, Map>();
int i=0;
myMap.put(i++, first);
myMap.put(i++, second);
myMap.put(i++, third);
myMap.put(10, other);

如果地图真的不起作用,正如你所说的那样。然后我会建议在ArrayList周围创建一个Decorator。在insert方法中,添加空值以填充空位置。我建议使用Guava的ForwardingList来简化课程的创建。这样你只需要实现一种方法。

答案 6 :(得分:0)

不,你不能这样做, 但是如果你想这样做,那么在剩下的索引中添加空对象,比如..

    ArrayList<Object> items = new ArrayList<Object>();
    items.add(new Object());
    items.add(new Object());
    items.add(new Object());
    items.add(3,new Object());

答案 7 :(得分:0)

如果内存和索引非常重要,请使用普通数组。

当它变为小用System.arraycopy时,就像ArrayList在内部做的那样。

-

即使您使用ArrayList并拥有Million Objects,建议使用ArrayList(int initialCapacity)-Constructor来避免大量复制操作

答案 8 :(得分:0)

@ icCube-你说,那个名单应该是90%左右。 我对这个解决方案的想法是:

  • 如果您确切知道目标大小 - 请使用plain array
  • 如果您了解目标大小 - 请使用ArrayList,其初始容量尽可能接近目标大小。正如人们所言,将空值与l.addAll(Collections.nCopies(n, (String)null));放在一起。
  • 如果您不知道目标大小 - 您的ArrayList将多次调整大小。调整大小意味着复制整个底层数组(它使用Arrays.copyOf)。你可以想象如果复制数组会发生什么 - GC有很多工作要做。然后使用TreeMap。

答案 9 :(得分:-2)

使用构造函数ArrayList(int initialCapacity)。这样您就可以设置初始容量。