简体   繁体   English

java arraylist ensureCapacity无法正常工作

[英]java arraylist ensureCapacity not working

Either I'm doing this wrong or i'm not understanding how this method works. 要么我做错了,要么我不理解这种方法是如何工作的。

ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
a.add(190,"test");
System.out.println(a.get(190).toString());

I would have thought that ensureCapacity would let me insert a record with an index up to that value. 我原以为ensureCapacity会让我插入一个索引达到该值的记录。 Is there a different way to do this? 有没有不同的方法来做到这一点?

I get an IndexOutOfBounds error on the third line. 我在第三行得到一个IndexOutOfBounds错误。

No, ensureCapacity doesn't change the logical size of an ArrayList - it changes the capacity , which is the size the list can reach before it next needs to copy values. 不, ensureCapacity不会更改ArrayList逻辑大小 - 它会更改容量 ,即列表在下次需要复制值之前可以达到的大小。

You need to be very aware of the difference between a logical size (ie all the values in the range [0, size) are accessible, and adding a new element will add it at index size ) and the capacity which is more of an implementation detail really - it's the size of the backing array used for storage. 您需要非常了解逻辑大小(即范围[0, size)中的所有值都可访问,并且添加新元素将以索引size添加它)和更多实现的容量之间的差异细节真的 - 它是用于存储的后备阵列的大小。

Calling ensureCapacity should only ever make any difference in terms of performance (by avoiding excessive copying) - it doesn't affect the logical model of what's in the list, if you see what I mean. 调用ensureCapacity应该只在性能方面做出任何改变(通过避免过度复制) - 如果你看到我的意思,它不会影响列表中的内容的逻辑模型。

EDIT: It sounds like you want a sort of ensureSize() method, which might look something like this: 编辑:听起来你想要一种ensureSize()方法,它可能看起来像这样:

public static void ensureSize(ArrayList<?> list, int size) {
    // Prevent excessive copying while we're adding
    list.ensureCapacity(size);
    while (list.size() < size) {
        list.add(null);
    }
}

So as others have mentioned ensureCapacity isn't for that. 因此,正如其他人提到的那样, ensureCapacity并非如此。 It looks like you want to start out with an ArrayList of 200 nulls? 看起来你想从一个200个空的ArrayList开始? Then this would be the simplest way to do it: 那么这将是最简单的方法:

ArrayList<String> a = new ArrayList<String>(Arrays.asList( new String[200] ));

Then if you want to replace element 190 with "test" do: 然后,如果你想用“test” 替换元素190,请执行以下操作:

a.set(190, "test");

This is different from 这不同于

a.add(190, "test");

which will add "test" in index 190 and shift the other 9 elements up, resulting in a list of size 201. 这将在索引190中添加“test”并将其他9个元素向上移动,从而得到大小为201的列表。

If you know you are always going to have 200 elements it might be better to just use an array. 如果你知道你总是会有200个元素,那么使用数组可能会更好。

Ensuring capacity isn't adding items to the list. 确保容量不会将项目添加到列表中。 You can only get element 190 or add at element 190 if you've added 191 elements already. 如果已经添加了191个元素,则只能获取元素190或添加元素190。 "Capacity" is just the number of objects the ArrayList can hold before it needs to resize its internal data structure (an array). “容量”只是ArrayList在需要调整其内部数据结构(数组)大小之前可以容纳的对象数。 If ArrayList had a getCapacity(), then doing this: 如果ArrayList有一个getCapacity(),那么这样做:

ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
System.out.println(a.size());
System.out.println(a.getCapacity());

would print out 0 and some number greater than or equal to 200, respectively 将分别打印出0和大于或等于200的某个数字

ArrayList maintains its capacity (the size of the internal array) separately from its size (the number of elements added), and the 'set' method depends on the index already having been assigned to an element. ArrayList保持其容量(内部数组的大小)与其大小(添加的元素数)分开,“set”方法取决于已经分配给元素的索引。 There isn't a way to set the size. 没有办法设置大小。 If you need this, you can add dummy elements with a loop: 如果需要,可以添加带循环的虚拟元素:

for (int i = 200; --i >= 0;) a.add(null);

Adding 190 null entries to an ArrayList reeks of a misuse of the data structure. 向ArrayList添加190个空条目会导致滥用数据结构。

  1. Think about using a standard primitive array. 考虑使用标准原始数组。

  2. If you require a generics or want more efficient use of space then consider SparseArray or even a Map like a HashMap may be appropriate for your purposes. 如果您需要泛型或想要更有效地使用空间,那么考虑SparseArray甚至像HashMap这样的Map可能适合您的目的。

  public static void fillArrayList(ArrayList<String> arrayList, long size) {
    for (int i = 0; i < size + 1; i++) {
      arrayList.add(i,"-1");
    }
  }

public static void main(String[] args) throws Exception {
  ArrayList<String> a = new ArrayList<String>(10);
  fillArrayList(a, 190);
  a.add(190,"test");
  System.out.println(a.get(190).toString());
}

Once again JavaDoc to clarify the situation: JavaDoc再一次澄清了这种情况:

Throws: IndexOutOfBoundsException 
    - if index is out of range (index < 0 || index > size()).

Note that size() returns the number of elements currently held by the List. 请注意, size()返回List当前持有的元素数。

ensureCapacity just makes sure that the underlying array's capacity is greater than or equal to the argument. ensureCapacity只是确保底层数组的容量大于或等于参数。 It doesn't change the size of the ArrayList . 它不会更改ArrayList的大小。 It does't make any changes visible through the API, so you won't notice a difference except that it will probably be longer before the ArrayList resizes it's internal array. 它不会通过API显示任何更改,因此除了在ArrayList调整其内部数组大小之前可能会更长时间之外,您不会注意到差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM