Some of the previous limitations can be overcome by suitably manipulating arrays, in such a way that the memory necessary to store the data of the application is allocated and deallocated dynamically during the program execution, depending on the needs.
The following example shows a class for dealing with a list of persons (objects of the class Person) that manages the size of the array dynamically.
public class ListOfPersonsArray { private Person[] a; private int n; public ListOfPersonsArray() { a = new Person[10]; n = 0; } // Add a person to the List of Persons in the last position public void add (Person p) { if (n == a.length) { // The array is full!!! // We have to create a new, bigger array and copy all elements Person[] b = new Person[a.length*2]; for (int i=0; i<a.length; i++) b[i] = a[i]; a = b; } // Now we are sure that n < a.length a[n] = p; n++; } // Remove the person in position k public void remove (int k) { if ((k >= 0) && (k < n)) { // We have to move all elements that follow k for (int i = k; i < n; i++) a[i] = a[i+1]; n--; } // We reduce the dimension of the array if it is sufficiently empty if ((a.length > 10) && (n < a.length/4)) { Person[] b = new Person[a.length/2]; for (int i = 0; i < n; i++) b[i] = a[i]; a = b; } } }
Note that the dynamic management of the array is not done by dynamically changing its dimension (which is not possible), but by creating a new bigger or smaller array according to the application needs, and copying all values to the new array each time this becomes necessary.
The dimension of a new dynamically created array is doubled when new elements are necessary, and halved when the array is sufficiently empty. The choice of considering the array sufficiently empty when n < a.length/4 allows us to minimize the number of times it is necessary to create a new array, since at most half of the elements of the newly created array are used the moment the array is created.