Why can't arrays be modified?

What is the reason why arrays, primitive or others, cannot be dynamically changed?

I know that you can use ArrayList , but the implementation behind it is still an array of initial size (in my opinion, this is 50 by default), and when it exceeds 50, a new array will be created containing these elements.

So, I am trying to understand the system specification of an array that makes it impossible.

+7
java arrays
source share
4 answers

This is the right question, and the answer is about how computers work.

When you create an array, for example, using int[] array = new int[5] , the computer reserves five consecutive memory spaces for the data that must be contained in this array. However, the memory spaces after this can be used immediately to store other information. If subsequently the size of the array must be changed, this other information must be moved to another location so that the array becomes larger. This is a lot of shuffling that we don’t want to deal with, so computer architects are not allowed to resize the array to simplify the work.

+5
source share

Suppose you define an array of 16 bytes, an integer, and another integer.

Now you want to resize it ...

 ====================================================== || || || || || || || || || || || || || || || || || || ---> (Memory) ====================================================== \________________/\____/\____/ ---------------- ---- ---- Array(16) Int Int 

Is it possible to resize an array higher?

A new array must be allocated for the next free memory block, since the program has already reserved blocks immediately after integers.

+3
source share

The array under the hood is a contiguous block of memory. Depending on what you initialize it for, it can be relatively small or relatively large.

Say, for example, I have an array of ten elements.

 int[] arr = new int[10]; 

At the core of the JVM implementation, you now need to request the OS for 40 contiguous bytes for the program. OS commits, and now you have 40 bytes that you can use with the familiar name arr .

Note that this array probably uses the space on either side of it - there are other links or a bit of information next to it, and it cannot just go to the eleventh position of itself and “require” it.

Let's say we decided 10 is too short. We need to make it bigger - ten times.

 int arr2 = new int[100]; 

Now the OS should find 400 bytes of space that are next to each other in memory, which may or may not be trivial, given the life cycle of objects, runtime garbage collection, etc.

Array scaling is not just about moving links to multiple memory locations — it's about finding new blocks of contiguous memory to store data.


You mentioned ArrayList - its curious that it is supported by an array that automatically resizes. Well, there is a trick for this resize operation - it's expensive.

 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } 

That ensureCapacityInternal does some interesting things ... ultimately calls ensureExplicitCapacity ... which ultimately calls grow :

 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } 

Essentially, every time it needs to be resized, it allocates a space equal to 1.5 times the original array. This greatly speeds up the expensive , if the ArrayList significantly large - the system must go out and find more and more contiguous memory for allocation, that is, the JVM must find some more space that is contiguous, which means more time spent garbage collection, and ultimately means less performance.

And the above does not even apply to copying data.

+3
source share

To solve this problem, vectors exist.

You should use vectors as dynamic memory allocation.

+2
source share

All Articles