Concepts / Array Basics in Java

Array Basics in Java

Arrays.copyOf(list, lengthOfCopy) returns a new array of the requested length, copying items from the original and filling any extra positions with default values

  • Programming

Why One Variable per Item Breaks Down

Suppose a program must process the names of one thousand people. The first idea many learners have is to declare one thousand variables to hold the names and write one thousand print statements to display them. That approach feels reasonable at first, but it becomes unworkable very quickly. An array is the structure designed for exactly this situation.

EASY

Before reading on, think about the thousand-name program written with one variable per item. Estimate how many variables you would have to declare, and how many lines of code you would have to write just to print every name. Write both numbers down before continuing.

Hints
  • Count the declarations first, then the print statements, one per name.
  • Ask yourself what changes if the list grows to ten thousand names.

An array solves the problem by keeping the whole list under a single name. One variable represents the entire collection, and you reach any individual item through its position in that collection. Instead of giving each person their own variable, the collection gets one variable, and each item is found by number.

An Array as a Numbered Sequence

Definition

An array is a data structure whose items are arranged as a numbered sequence. Because each item has a position number, any single item can be referred to by that number.

Two rules shape arrays in Java. First, every item in the array must be of the same type, called the base type. Second, the numbering always begins at zero. Some other programming languages do not impose the same-type rule, so this belongs to the Java setting rather than to arrays in general.

index 0Anaindex 1Benindex 2Chloeindex 3Devindex 4Eli
Which index holds which name? The first element sits at index 0, and the last element sits at index length minus one, which is index 4 for an array of length 5.

Read the diagram from left to right. The first name is at index 0 and the last name is at index 4. The highest index is always one less than the length, which follows directly from numbering that begins at zero. A learner who reads the first position as index 1 has made the most common indexing error, which is covered later in this article.

Length, Base Type, and Index in a Declaration

Three terms describe any array. The length is the number of items the array contains. The base type is the type shared by the individual items. The index is the position number of one particular item. Keeping these three apart is the key to reading array descriptions correctly.

java
Notes on the code
  • int[] : the base type is int, so every item must be an int
  • new int[5] : the length is 5, so the valid indices run from 0 to 4
  • scores[2] : the index 2 selects the third position, not the second
  • third : receives the value stored at index 2, which is 88
Worked example

Reading an Array Declaration

Given String[] names = new String[3]; identify the base type, the length, and the highest valid index.

  1. 1
    Base type

    The element type written before the brackets is String, so every item must be a String.

  2. 2
    Length

    The number inside the brackets in new String[3] is 3, so the array holds three items.

  3. 3
    Highest index

    Numbering starts at zero, so the indices are 0, 1, and 2. The highest index is length minus one, which is 2.

Result

Base type String, length 3, indices 0 through 2.

Elements Are Variables, Not Just Values

An array can be understood as a list of variables. An array of ints can be read as a list of variables of type int, and an array of Strings as a list of variables of type String. The source is explicit that an array is not, properly speaking, just a list of integers or strings. It is better thought of as a collection of variables, each of which can hold a value of the array's base type.

Definition

An element is one of the individual variables that make up an array. Each element can hold a value of the base type, and that value can be changed at any time, just as the value of an ordinary variable can be changed.

Tracing Arrays.copyOf Step by Step

Suppose you have an array and want a second array with the same values. Java provides the tool for this. The static method Arrays.copyOf lives in the class Arrays, which is in the package java.util. You call it with two things: the array to copy and the length you want the result to have. It returns a new array of that length, and the new array receives items copied from the original.

java
Output
[10, 20, 30, 0, 0]
[10, 20]
Notes on the code
  • Arrays.copyOf(original, 5) : requested length exceeds the original, so the two extra positions get the default value 0
  • Arrays.copyOf(original, 2) : requested length is smaller, so only the first two items fit and are copied
  • Arrays.toString is used only to display the arrays

The requested length controls how many items can be copied. When the requested length is larger than the original, the extra positions receive default values: zero for numeric arrays, null for object arrays, and so on. When the requested length is smaller than or equal to the original, only as many items are copied as will fit. The length argument alone decides the result's size, so the same method can produce a bigger array, a smaller array, or an exact duplicate.

Arrays.copyOf is a function, so it does not change its input. It hands back a fresh array. To keep the result, assign it to a variable. Writing the call without an assignment computes a copy that is immediately thrown away, so the program has nothing to use afterward.

Resizing is the main reason to use copyOf. Consider a list of players where only the first few positions hold real entries. Passing twice the current length produces a larger array in one line, which doubles the space available. Passing half the length produces a smaller array, which is useful when most of the space would otherwise sit empty. The source describes deleting a player by copying the last filled entry into the removed position and reducing the count. When the count falls below a quarter of the array's capacity, the array can be cut in half with copyOf. Entries beyond the new length are simply dropped, and the entries that survive are kept.

Copying with clone() and Its Limits

When you want a simple copy with exactly the same size as the original, there is a shorter route. Every array has an instance method named clone() that makes a copy of the array. You call it on the array itself rather than passing the array to a static method.

java
Output
10
Notes on the code
  • original.clone() : returns a same-size copy with the values 10, 20, 30
  • same[0] = 99 : changes only the copy, because the array holds primitive int values
  • original[0] still holds 10
FeatureArrays.copyOf(array, length)array.clone()
How it is calledStatic method in the Arrays class, passing the array inInstance method called on the array itself
Can it change size?Yes, the length argument sets the new sizeNo, it has no length argument and returns a same-size copy
Best used forResizing, including doubling or halvingA simple duplicate of the same size

Choosing between the two ways to copy an array

clone() has no length argument, so it cannot resize. If you need a different size, Arrays.copyOf is the tool. If you need only a same-size copy, clone() expresses that intent more directly.

When Copied Arrays Share Objects

The copying behavior above was described for arrays of numbers. Arrays of objects behave differently in one important way. The Arrays class contains a copyOf method for each primitive type and one for objects. When an array of objects is copied, only the references to the objects are copied into the new array. The contents of the objects are not copied. This is the usual rule for assignment of references, and the result is called a shallow copy.

original arraytwo slotsStringBuilder objectAcontents: acopy arraytwo slotsStringBuilder objectBcontents: breferencereferencereferencereference
After copying an array of objects, do the original and the copy point to the same object instances? Yes. Each array has its own slots, but both arrays hold references to the same two objects, so a change to an object is visible through either array.

What do you think happens?

After this code runs, what does the line printing boxes[0] show?

  • a

  • ax

  • x

Reveal answer
Answer:

ax

The copy holds the same reference to the first StringBuilder object as the original. Appending x through the copy changes the object that boxes[0] also refers to, so the original shows ax.

java
Output
ax
Notes on the code
  • boxes and copy are two different arrays with their own slots
  • copy[0] and boxes[0] both lead to the same StringBuilder object
  • append changes the object's contents, which both arrays see

Mistakes Beginners Make with Copies and Indices

  • Common mistake

    Treating the first position as index 1

    What it looks like

    For int[] scores = new int[5];, using scores[5] as the first item.

    Why it fails

    Numbering always begins at zero, so the valid indices run from 0 to 4 and index 5 is outside the array.

    Do this instead

    Use scores[0] for the first item and scores[4] for the last.

  • Common mistake

    Expecting copyOf to change the original array

    What it looks like
    Arrays.copyOf(original, 5); with no assignment, then printing original.length.
    Why it fails

    copyOf is a function. It returns a fresh array and leaves its input unchanged, so the new array is discarded.

    Do this instead
    Assign the result, as in int[] bigger = Arrays.copyOf(original, 5);.
  • Common mistake

    Assuming clone() can resize an array

    What it looks like
    Expecting original.clone() to produce a longer array.
    Why it fails

    clone() takes no length argument and returns a copy of the same size.

    Do this instead

    Use Arrays.copyOf(original, newLength) when the size must change.

  • Common mistake

    Assuming copying an object array duplicates the objects

    What it looks like

    Changing copy[0].append("x") and expecting boxes[0] to stay unchanged.

    Why it fails

    A shallow copy copies only the references, so both arrays lead to the same object.

    Do this instead

    If independent objects are needed, create new objects for the copy rather than relying on clone or copyOf.

When a copied array produces a surprising result, work through the sequence in order. First, identify whether the copy was made with Arrays.copyOf or clone(), and what size you expected. Second, check whether the array holds primitive values or object references. Third, check whether a later line changed the array through the copy or through the original. Each check points to a specific place where the result could diverge.

Practice: Predict Before You Run

MEDIUM

Trace this code by hand. Declare int[] a = {4, 8, 15}; then int[] b = Arrays.copyOf(a, 2); then a[1] = 100; then b[1] = 7;. Predict the contents of a and b at the end, including their lengths, before checking your answer.

Hints
  • Arrays.copyOf with length 2 copies only the first two items, so b starts as 4 and 8.
  • Both arrays hold primitive ints, so changing one array does not change the other.
  • Count the length of b after the copy: it is 2, not 3.

Key Takeaways

  • An array is a data structure whose items form a numbered sequence, with one base type shared by every item and numbering that always starts at zero. Its highest index is always length minus one.
  • Each element is a storage position that can hold a value of the base type, and that value can be replaced without changing the position itself.
  • Arrays.copyOf(array, length) returns a new array of the requested length, copying items that fit and filling extra positions with default values. It can double or halve an array's capacity, but it must be assigned to a variable to be kept.
  • clone() makes a same-size copy as an instance method and cannot resize an array.
  • Copying an array of objects produces a shallow copy: both arrays hold references to the same objects, so changes to an object are visible through both.