JavaRush /Java Blog /Random EN /new ArrayList(????) how and where is it better to initial...
Vovan
Level 22

new ArrayList(????) how and where is it better to initialize

Published in the Random EN group
Writing code without using the collections framework would be crazy. This is a wonderful piece of Java with many neat solutions. More importantly, unlike arrays, you don't have to worry about sizes. The ArrayList will grow until it runs out of memory. The developer doesn't have to worry about the initial size and the ArrayIndexOutOfBoundsException error . But what if there is a condition to monitor the amount of memory? Can we use memory efficiently when working with collections?
A standard question arises: how to initialize a list? The code below will not work: It will result in a compilation error: The local variable names may not have been initialized . The Java specification requires that all local variables (those that exist on the stack) be initialized with appropriate values. This is how you can do it: Without a doubt, the list must be initialized. You can either create the list on the first line, or you can do something smarter and use lazy initialization like we did in the getAllNames() method . In this case, the list will only be created when necessary - if the initial conditions are not met, the list will never appear on the heap. Here we come to the main question: what size should we set for the list? The best option is to give him the exact size. For example: In this case, exactly n names must be returned, and as a consequence, a collection of n elements is created. However, the exact value of n is not always known. Even in the example given, what if n=1000 and there were only 100 names available? When working with collections, the most popular method is to call the default constructor. If you look at the Java source code (version 1.6) As you can see, by default a list of 10 elements is created . That is, we can safely use the default constructor when we do not plan to store more than 10 elements in the list. What happens if you try to add the 11th element? Well, nothing bad... the element will be added successfully. Look at the method: The size of the array is controlled by the ensureCapacity method . The size increases by 1.5 times . A new array is created and the elements are moved into it. If we set the size to 10, then on the 11th element:
public List getAllNames() { List names; if (/*необходимые условия выполнены*/) { names = new ArrayList (); /*заполнение списка*/ } return names; }
List names = null; List names = new ArrayList (); List names = new ArrayList (0); List names = new ArrayList (size);
public List getTopNames (int n) { List names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList (n); /*заполнение списка*/ } return names; }
names = new ArrayList ();

/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; } public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
  • size changes to 10 * 3 / 2 + 1 = 16
  • next increase = 16 * 3 / 2 + 1 = 25
  • next increase = 25 * 3 / 2 + 1 = 39 and so on.
In case of 100 elements, the JVM will need to create a new array several times and copy the elements into it. Taking this into account, if there is an assumption about the required size of the array, it is better to set the initial capacity close to it. Here are some guidelines for action:
  1. Create a collection only when you need it , otherwise initialize it to null or use Collections.EMPTY_LIST .
  2. If you know the exact size required , specify it in the collection constructor.
  3. If you are sure that the number of elements will not exceed 10 , feel free to use the default constructor.
  4. The risk associated with creating a zero-size collection is that the frequency of creating new arrays and copying data may be higher. You need to think very carefully about whether the benefit of using zero-size collections is really that great .
  5. If you initialized a collection too large at the beginning of the method and want to reduce it, there is the trimToSize() method .
Of course, these guidelines apply when working with array-based collections, and none of this makes sense in the case of a linked list. In fact, these problems are unlikely to be killers of the program, but if there is an opportunity to do a little better, why not use it. Do you have any other helpful tips? Have you found ways to make things work better? Or is this all unnecessary? What do you think?
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION