Standard Array Methods
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
Predicting What a Copy Produces
Suppose you have an array and you want a second array with the same values. It seems like a task Java should already handle, and it does. The useful question is what you actually get when you ask for a copy, and where the copy and the original start to differ. Before reading on, make a prediction about the program below.
What do you think happens?
What does the second line print when the program runs: [1, 2, 3, 0, 0] or [1, 2, 3]?
Reveal answer
[1, 2, 3, 0, 0]
Arrays.copyOf builds a new array of length 5. The three original items are copied into the first three positions, and the two extra positions receive the default value 0 for an int array.
Where the Array Methods Live
Java includes standard array-processing methods so that common jobs like copying do not have to be hand-written each time. Without them, copying an array means creating a new array of the same size and writing a loop that copies each element across, one index at a time. That works, but every programmer who needs a copy would write the same loop again.
The standard array-processing methods are static methods defined in a class named Arrays, which lives in the package java.util. The method that copies arrays is Arrays.copyOf.
Notice the naming pattern. The method belongs to the class Arrays, not to an individual array variable. Whether the array is small or large, the method is reached through the same class name, and the array you want to process is passed in as an argument. A call to copyOf takes two things: the array to copy, and the length you want the result to have. The call returns a new array of that length, filled with items copied from the original.
[1, 2, 3, 0, 0]
[1, 2, 3]- import
java.util.Arraysbrings the Arrays class into scope Arrays.copyOf(original, 5)is a static call: the class name comes first, then the method name, then the argumentsoriginal.clone()is an instance call made on the array itself, with no length argumentArrays.toStringis used only to display the contents of each array
Tracing a Copy Step by Step
The requested length controls how many items can be copied. When the requested length is larger than the original, the extra positions in the new array 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 is the one thing that decides the size of the result, so the same method can produce a bigger array, a smaller array, or an exact duplicate.
Copying a Score Array to a Longer Length
Start with int[] scores = {10, 20, 30}. Predict the contents of the array returned by Arrays.copyOf(scores, 4), then check what happens to scores itself.
- 1Step 1: Read the arguments
The first argument is the array to copy, scores. The second argument is the requested length, 4, which is larger than
scores.length, which is 3. - 2Step 2: Copy the matching positions
Positions 0, 1, and 2 of the original are copied into positions 0, 1, and 2 of the new array, giving 10, 20, and 30.
- 3Step 3: Fill the extra position
Position 3 of the new array has no original item to copy from, so it receives the default value 0 for an int array.
- 4Step 4: Check the original
copyOfdoes not change its input. The scores array still has length 3 and still holds 10, 20, 30. - 5Step 5: Keep the result
Calling
Arrays.copyOf(scores, 4)without assigning its result computes a copy that is then discarded. The result must be stored in a variable, for example int[] bigger =Arrays.copyOf(scores, 4).
bigger holds [10, 20, 30, 0]. scores is unchanged and still holds [10, 20, 30].
Resizing by Doubling and Halving
The same call that makes a copy can change how much room an array has. This matters when an array is only partly used, for example 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.
[10, 20, 30, 40, 0, 0, 0, 0]
[10, 20]scores.length* 2 requests twice the current length, so the new array has room for four more itemsscores.length/ 2 requests half the length, so only the first two items fit- Each call returns a new array, which is stored in its own variable
Shrinking works by copying as many items as fit and dropping the rest. Consider removing an entry from a list of players: one approach is to copy the last filled entry into the position being removed and reduce the count of players. If the count falls below a quarter of the array's capacity, the array can be cut in half with copyOf. Arrays.copyOf does not treat the surviving entries specially. It copies as many items as fit, so the entries that survive the halving are kept and the spare positions are dropped.
Choosing Between copyOf and clone
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. clone() has no length argument, so it cannot resize. If you need a different size, Arrays.copyOf is the tool to use. If you need only a same-size copy, clone() is the more direct expression of that intent.
| Feature | Arrays.copyOf | clone() |
|---|---|---|
| Kind of method | Static method in the Arrays class | Instance method on the array itself |
| Call form | Arrays.copyOf(list, length) | list.clone() |
| Length argument | Required, and sets the size of the result | None, so the copy is the same size |
| Can resize | Yes, larger or smaller | No |
| Result | A new, separate array | A new, separate array |
Two ways to create a copy of an array in Java
Copying Arrays of Objects
The copying behavior described so far applies to 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 objects themselves are not copied. This is the usual rule for assignment of references, and the result is called a shallow copy.
import java.util.Arrays;
public class ShallowDemo {
public static void main(String[] args) {
StringBuilder[] original = { new StringBuilder("A"), new StringBuilder("B") };
StringBuilder[] copy = Arrays.copyOf(original, original.length);
copy[0].append("X");
System.out.println(original[0]);
System.out.println(copy[0] == original[0]);
}
}- 1Line 4 creates an array of two
StringBuilderreferences, each pointing to a new object. - 2Line 5 copies the array with
copyOf. The new array holds the same two references, not new copies of the objects. - 3Line 6 calls append on the object reached through copy[0], changing it from A to AX.
- 4Line 7 prints original[0], which reaches the same object and therefore shows AX.
- 5Line 8 prints true because both array slots refer to the same object.
- Each array slot holds a reference to a
StringBuilderobject copyOfcopies the references, so copy[0] and original[0] refer to the sameStringBuilder- append changes the shared object, so the change is visible through both arrays
AX
trueOne Name, Many Overloads
The source makes a point that is easy to skim past: the methods in the Arrays class, copyOf included, come in multiple versions, and each version is written for a different array type. Arrays.copyOf is therefore not one method that handles every kind of array in exactly one way. It is a family of methods that share a name, with each member written for one kind of array.
When you call the method, Java selects the version that matches the array you pass in. Passing an int array selects the int version, and passing a String array selects the object version. You do not need to remember a separate name for each array type. You need to make sure the array you pass in is the type you intend to copy.
Store the result of every copying call in a variable of the matching array type, such as int[] or String[]. The declared type then makes it clear which version of the method you meant, and it keeps the copy available for later use.
Mistakes When Copying Arrays
Common mistake Calling Arrays.copyOf without assigning its result
What it looks likeArrays.copyOf(scores, 6); followed by a print of scoresWhy it failscopyOfis a function. It does not change its input, so scores is unchanged and the new array is thrown away.Do this insteadint[] bigger = Arrays.copyOf(scores, 6); and then use bigger.Common mistake Expecting clone() to resize an array
What it looks likeint[] bigger = scores.clone(); when a larger array is neededWhy it failsclone()has no length argument, so it produces a copy of the same size only.Do this insteadUse Arrays.copyOf(scores, newLength) when the size must change.
Common mistake Assuming an object array copy is independent of the original
What it looks likeChanging copy[0] through append and expecting original[0] to stay the same
Why it failsA copy of an object array holds the same object references, so changes to the objects are shared.
Do this insteadExpect shared objects after copying, and create new objects where independent contents are required.
Common mistake Forgetting the default values in the extra positions
What it looks likeExpecting copyOf(numbers, 5) to contain only the original values
Why it failsA longer result fills the extra positions with default values: zero for numeric arrays and null for object arrays.
Do this insteadExpect 0 or null in the added positions, and set real values there before relying on them.
Practice Predicting a Copy
Given int[] nums = {4, 8, 15}; int[] bigger = Arrays.copyOf(nums, 6); bigger[1] = 99; predict the contents of bigger and the value of nums[1] after these lines run. Explain your answer by pointing to where the copy stopped sharing with the original.
Hints
- Ask first whether
copyOfmakes a new array or changes nums. - Look at which original positions are copied and what the extra positions contain.
- An int array stores numbers directly, so assigning to bigger[1] does not affect nums.
Key Takeaways
- Java's standard array-processing methods are static methods in the Arrays class, in the package
java.util, and are called with the class name, the method name, and the arguments. Arrays.copyOf(array, length)returns a new array of the requested length, copies items by position, fills extra positions with default values, and does not change its input.- Doubling or halving the length with
copyOfresizes a partly used array, whileclone()makes only a same-size copy and takes no length argument. - Copying an array of objects produces a shallow copy, so the new array shares the same object instances with the original.
- The Arrays class provides one version of its methods for each array type, and Java selects the version that matches the array passed in.