java arraylist ensureCapacity not working

久未见 提交于 2019-12-17 10:54:10

问题


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. Is there a different way to do this?

I get an IndexOutOfBounds error on the third line.


回答1:


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.

You need to be very aware of the difference between a logical size (i.e. 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.

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.

EDIT: It sounds like you want a sort of ensureSize() method, which might look something like this:

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



回答2:


So as others have mentioned ensureCapacity isn't for that. It looks like you want to start out with an ArrayList of 200 nulls? 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:

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.

If you know you are always going to have 200 elements it might be better to just use an array.




回答3:


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. "Capacity" is just the number of objects the ArrayList can hold before it needs to resize its internal data structure (an array). If ArrayList had a getCapacity(), then doing this:

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




回答4:


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



回答5:


Once again JavaDoc to clarify the situation:

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.




回答6:


ensureCapacity just makes sure that the underlying array's capacity is greater than or equal to the argument. It doesn't change the size of the 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.




回答7:


Adding 190 null entries to an ArrayList reeks of a misuse of the data structure.

  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.




回答8:


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


来源:https://stackoverflow.com/questions/7688151/java-arraylist-ensurecapacity-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!