Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.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 ArrayList添加当前大小以外的项_Java_Arraylist - Fatal编程技术网

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

Java ArrayList添加当前大小以外的项,java,arraylist,Java,Arraylist,想知道是否有一种有效的方法可以将项目添加到Java的ArrayList中比其当前大小更大的位置: 情景: ArrayList<Item> items = new ArrayList<Item>; ... let's say I add three elements 有没有一种有效的方法可以用空值调整/填充ArrayList Java的实现使大小字段成为私有的:-(..使用构造函数ArrayList(int initialCapacity)。这样可以设置初始容

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

情景:

   ArrayList<Item> items = new ArrayList<Item>;
   ... let's say I add three elements
有没有一种有效的方法可以用空值调整/填充ArrayList


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

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

不,不能:

,E)

抛出:IndexOutOfBoundsException-如果索引超出范围 (索引<0 | |索引>大小()

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

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);
sortedmap myMap=newtreemap();
int i=0;
put(i++,第一);
myMap.put(i++,秒);
put(i++,第三);
myMap.put(10个,其他);
如果地图真的不起作用,就像你说的。然后我建议围绕ArrayList创建一个装饰器。在insert方法中,添加NULL以填充空位置。我建议使用番石榴来简化课程的创建。这样,您只需实现一种方法。

不,您不能这样做, 但如果您希望这样做,则在剩余索引中添加空对象,如

    ArrayList<Object> items = new ArrayList<Object>();
    items.add(new Object());
    items.add(new Object());
    items.add(new Object());
    items.add(3,new Object());
ArrayList items=new ArrayList();
添加(新对象());
添加(新对象());
添加(新对象());
添加(3,新对象());

我想你能做的最好的事情是
items.addAll(Collections.nCopies(6,null))
并且希望ArrayList实现一些行为来在内部加快这一点

这怎么样

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

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

当它变得很小时,ArrayList就是这样做的

--


即使您使用ArrayList并拥有一百万个对象,也建议使用ArrayList(int initialCapacity)-构造函数以避免大量复制操作

改用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);

            }
    }
公共类测试{
公共静态void main(字符串[]args)引发InterruptedException{
String s=“Lorem ipsum door sit amet,concertetur adipiscing elite.Quisque metus.”;
//测试1
ArrayList l=新的ArrayList();
对于(int i=0;i<1000000;i++){
l、 加上(s+“”+i);
l、 addAll(Collections.nCopies(i%10,(String)null));//添加一些null
}
//堆大于5MB
//测试2取消注释和注释测试1
//SortedMap map=新树映射();
//对于(int i=0;i<1000000;i++){
//map.put(i,s+“”+i);
//          }
//堆小于5MB
睡眠(100000);
}
}

看起来
TreeMap
版本比ArrayList版本占用的内存更少。检查你自己。

@icCube-你说过,这个列表应该已经满了90%。 我对此解决方案的想法是:

  • 如果您确切知道目标大小,请使用普通数组
  • 如果您知道目标大小,请使用初始容量尽可能接近目标大小的ArrayList。将null与
    l.addAll(Collections.nCopies(n,(String)null))放在一起
    
  • 如果您不知道目标大小,您的ArrayList将被调整多次大小。调整大小意味着复制整个基础数组(它使用Arrays.copyOf)。您可以想象,如果阵列被复制,会发生什么-GC有很多工作要做。然后使用树形图


这是一个较老的问题,但您现在可以使用
SparseArray
作为
ArrayList
的直接替代品。它允许非连续整数键值,如果尚未为键设置值,则返回null。性能方面,它完全是为您的需要而设计的。您使用的不是
add
,而是
append
,后者更具描述性,因为您将在max键的末尾追加,即使存在间隙。您也可以
设置
任何想要的键值,即使它超出了最大键值。

InitialCapacity不是线程“main”java.lang.IndexOutOfBoundsException:Index:9,size:0Try:public static void main(String[]args){ArrayList=new ArrayList(10);list.add(9,3);}您可能应该改用HashMap或SortedMap。好的,使用Map并不能解决内存不足的问题,我们知道最终结构已满->TIntObjectHashMap(trove)可能是HashMap不支持顺序。分类地图是一个更好的选择。内存原因是什么?为什么您会认为映射使用的内存比列表多得多?一种方法是调用
add(null)<1/代码> 8个时间。事实上,我有一个更优雅的东西:-1MIO对象的树图是1MIO对象的粗大的列表,中间的空缺要小得多。ARAYLIST主要是满的。使用<代码> 10个项目。大小<代码> >而不是<代码> 7 >代码>作为一个更健壮的选项。这很好,但是从性能点来看有点吓人。viewwell nCopies只为数组生成一个列表包装器,通过这种方式,您的ArrayList可以使用System.arraycopy来填充空值,这取决于它实现的智能程度Public boolean addAll(CollectionVoila,但您的解决方案是迄今为止最好的一个:-)那么“从性能角度看”这到底在哪里可怕的是,与多次调用add(null)相比(如果我们假设数字不固定的话)?Peter ArrayList是一个数组,仅此而已。一个完整的数组怎么可能比任何其他结构占用更多的大小。。。我认为你的例子有一个问题(我肯定)数组是(s-string,n-null):SNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNN。。。等有大量的内存保留的参考,但
[0, 1, 2, null, null, null, null, null, null, null, 10]
    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);

            }
    }