想知道是否有一种有效的方法将项目添加到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的实现使大小字段变为私有: - (..
答案 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%左右。 我对这个解决方案的想法是:
l.addAll(Collections.nCopies(n, (String)null));
放在一起。答案 9 :(得分:-2)
使用构造函数ArrayList(int initialCapacity)
。这样您就可以设置初始容量。