AI InterviewSearch…Search problems, topics, or pages…Ctrl KGet started
Skip to content

06 Arrays / Lesson 3 of 5

The Arrays class and System.arraycopy

13 min · +10 XP · 2 exercises · 5 questions

Read the text13 min
Exercises0/2
Quiz5 q

Quick answer

What is the Arrays class in Java?

The java.util.Arrays class is a set of static helper methods for arrays, which themselves have only a length field. It prints (Arrays.toString), compares (Arrays.equals), sorts (Arrays.sort), searches (Arrays.binarySearch), fills, copies (Arrays.copyOf) and converts arrays (Arrays.asList, Arrays.stream). System.arraycopy, a native bulk copy into an existing array, sits alongside it.

Arrays themselves have one field and no useful methods. Everything you actually do with them — sort, search, fill, copy, compare, print, convert — lives in java.util.Arrays, a class of static helpers, plus one native method in System. Knowing this toolkit saves writing loops and, more importantly, saves writing wrong loops.

Printing and comparing

int[] a = {3, 1, 2};
Arrays.toString(a)            // "[3, 1, 2]"
Arrays.deepToString(grid)     // nested arrays
Arrays.equals(a, b)           // same length and equal elements, in order
Arrays.deepEquals(g1, g2)     // nested
Arrays.hashCode(a)            // content-based hash (for using arrays as map keys — better to avoid)
Arrays.compare(a, b)          // lexicographic, Java 9+
Arrays.mismatch(a, b)         // index of the first difference, or -1

a.equals(b) and a.hashCode() are Object's — identity. This is why an int[] as a HashMap key never matches another array with the same contents; use a List or a record instead.

Sorting

Arrays.sort(a);                       // ascending, in place; primitives use dual-pivot quicksort, O(n log n)
Arrays.sort(a, 1, 4);                 // a range [from, to)
Arrays.sort(strings);                 // natural order (compareTo); objects use TimSort, stable
Arrays.sort(strings, String.CASE_INSENSITIVE_ORDER);
Arrays.sort(people, Comparator.comparing(Person::age));      // any Comparator (Module 14)
Arrays.sort(boxed, Collections.reverseOrder());              // Integer[] descending
Arrays.parallelSort(big);             // multi-threaded for large arrays

There is no descending sort for a primitive array — Arrays.sort(int[], Comparator) does not exist because comparators take objects. Sort ascending and read backwards, negate the values, or box to Integer[]. Sorting is stable for objects (equal elements keep their order) and, being in place on primitives, unstable in the sense that does not matter for values.

For a 2D array by a column: Arrays.sort(rows, (x, y) -> Integer.compare(x[0], y[0])); — int[][] is an array of objects, so a comparator applies.

Searching

int i = Arrays.binarySearch(sorted, 7);     // index, or -(insertionPoint) - 1 if absent; array MUST be sorted

On an unsorted array the result is meaningless. A negative return encodes where the value would go: -(r + 1) is the insertion point — useful for "first element ≥ x". For a linear search on an unsorted array there is no helper; write the loop or Arrays.asList(objs).indexOf(x) for object arrays.

Filling and creating

Arrays.fill(a, -1);                  // every element
Arrays.fill(a, 2, 5, 0);             // a range
Arrays.setAll(a, i -> i * i);        // compute each element from its index (Java 8+)
int[] sq = IntStream.range(0, 5).map(i -> i * i).toArray();   // 0 1 4 9 16

Arrays.fill on a 2D array fills the outer array with the same row reference — Arrays.fill(grid, new int[4]) makes every row the same object. Fill each row: for (int[] row : grid) Arrays.fill(row, -1);.

Copying

int[] copy = Arrays.copyOf(a, a.length);      // a full copy
int[] longer = Arrays.copyOf(a, 10);          // copied and padded with zeros — how ArrayList grows
int[] part = Arrays.copyOfRange(a, 1, 3);     // [from, to)
int[] c = a.clone();                          // also a full copy
System.arraycopy(a, 0, dest, 2, 3);           // (src, srcPos, dest, destPos, length): 3 elements from a[0] into dest[2..4]

System.arraycopy is the primitive the others are built on — a native, bulk memory copy that handles overlapping ranges correctly (so System.arraycopy(a, 0, a, 1, n - 1) shifts right in place). It throws ArrayIndexOutOfBoundsException if either range is out of bounds and ArrayStoreException for a type mismatch. All of these are shallow: for object arrays they copy references.

Converting

List<Integer> list = Arrays.asList(boxed);    // FIXED-SIZE view over the array: set() works, add()/remove() throw
List<String> l2 = Arrays.asList("a", "b");    // varargs — same fixed-size view
List<Integer> real = new ArrayList<>(Arrays.asList(boxed));   // a growable copy
List<int[]> oops = Arrays.asList(intArray);   // an int[] is ONE element — primitives are not boxed
List<Integer> ok = Arrays.stream(intArray).boxed().toList();  // the right way for int[] (Java 16 toList)
Integer[] back = list.toArray(new Integer[0]);
IntStream s = Arrays.stream(a);               // sum(), max(), filter(), … (Module 15)
int sum = Arrays.stream(a).sum();
int max = Arrays.stream(a).max().getAsInt();

Two traps in asList: it is a view backed by the array (changes go both ways; size cannot change), and it does not box primitive arrays — Arrays.asList(new int[]{1,2}) is a list with one element, the array. List.of(...) (Java 9) is the immutable alternative and rejects nulls.

Streams over arrays (a preview)

Arrays.stream(a) opens the door to sum, average, max, filter, map, sorted, distinct, anyMatch — one-liners for many loop patterns. Module 15 covers streams; until then, Arrays.stream(a).sum() and .max().getAsInt() are safe to use as vocabulary.

Utility methods you will write yourself

The JDK has no Arrays.reverse, Arrays.max for int[] (outside streams), Arrays.indexOf, Arrays.contains or Arrays.swap. They are five-line helpers; in interviews write them, in projects keep them in a small util class or use a library like Guava/Commons.

Interview angle

  • "How do you sort an int[] descending?" No comparator on primitives: sort ascending and reverse, or box.
  • "Arrays.asList(new int[]{1,2}).size()?" 1.
  • "What does Arrays.binarySearch return when the value is absent?" -(insertionPoint) - 1.
  • "Difference between Arrays.copyOf and System.arraycopy?" copyOf allocates a new array of a given length; arraycopy copies into an existing one and can overlap.
  • "Can you add to Arrays.asList?" No — UnsupportedOperationException; wrap in new ArrayList<>(…).

Key takeaways

  • Arrays.toString/equals/hashCode for contents; the array's own methods are identity-based.
  • Arrays.sort (no descending for primitives), binarySearch (sorted only, negative = insertion point), fill, setAll.
  • copyOf/copyOfRange/clone/System.arraycopy — all shallow; arraycopy handles overlap.
  • Arrays.asList is a fixed-size view and does not box primitives; Arrays.stream for int[].

Common questions

How do you print an array in Java?

Call Arrays.toString(a), which gives [3, 1, 2], or Arrays.deepToString for nested arrays. Printing the array itself uses Object.toString and shows a type code and hash such as [I@1b6d3586 instead of the contents.

How do you sort an int array in descending order in Java?

There is no descending sort for a primitive array, because Arrays.sort accepts a Comparator only for object arrays. Sort ascending and read or reverse it backwards, negate the values, or box to Integer[] and call Arrays.sort(boxed, Collections.reverseOrder()).

Why does add on Arrays.asList throw UnsupportedOperationException?

Arrays.asList returns a fixed-size view backed by the array: set works and writes through to the array, but add and remove would change its size. Wrap it in new ArrayList<>(Arrays.asList(...)) for a growable copy. It also does not box primitives, so an int[] becomes one element.

What is the difference between Arrays.copyOf and System.arraycopy?

Arrays.copyOf allocates and returns a new array of the length you give, padded with defaults or truncated. System.arraycopy(src, srcPos, dest, destPos, length) copies into an existing array and handles overlapping ranges correctly. Both are shallow copies.

What does Arrays.binarySearch return if the element is not found?

It returns -(insertionPoint) - 1, a negative number that encodes where the value would go to keep the array sorted. The array must already be sorted; on an unsorted array the result is meaningless.

Mark as readSign in to keep your place.

Java Arrays Class: sort, binarySearch, asList and arraycopy

java.util.Arrays holds the static helpers for Java arrays: toString, equals, sort, binarySearch, fill, copyOf and asList, plus System.arraycopy and their traps.

  • Course: Java study plan
  • Module: Arrays
  • Kind: Lesson
  • Reading time: 13 min
  • Runtime: OpenJDK 18

What is the Arrays class in Java?

The java.util.Arrays class is a set of static helper methods for arrays, which themselves have only a length field. It prints (Arrays.toString), compares (Arrays.equals), sorts (Arrays.sort), searches (Arrays.binarySearch), fills, copies (Arrays.copyOf) and converts arrays (Arrays.asList, Arrays.stream). System.arraycopy, a native bulk copy into an existing array, sits alongside it.

Lesson

Arrays themselves have one field and no useful methods. Everything you actually do with them — sort, search, fill, copy, compare, print, convert — lives in java.util.Arrays, a class of static helpers, plus one native method in System. Knowing this toolkit saves writing loops and, more importantly, saves writing wrong loops.

Printing and comparing

int[] a = {3, 1, 2};
Arrays.toString(a)            // "[3, 1, 2]"
Arrays.deepToString(grid)     // nested arrays
Arrays.equals(a, b)           // same length and equal elements, in order
Arrays.deepEquals(g1, g2)     // nested
Arrays.hashCode(a)            // content-based hash (for using arrays as map keys — better to avoid)
Arrays.compare(a, b)          // lexicographic, Java 9+
Arrays.mismatch(a, b)         // index of the first difference, or -1

a.equals(b) and a.hashCode() are Object's — identity. This is why an int[] as a HashMap key never matches another array with the same contents; use a List or a record instead.

Sorting

Arrays.sort(a);                       // ascending, in place; primitives use dual-pivot quicksort, O(n log n)
Arrays.sort(a, 1, 4);                 // a range [from, to)
Arrays.sort(strings);                 // natural order (compareTo); objects use TimSort, stable
Arrays.sort(strings, String.CASE_INSENSITIVE_ORDER);
Arrays.sort(people, Comparator.comparing(Person::age));      // any Comparator (Module 14)
Arrays.sort(boxed, Collections.reverseOrder());              // Integer[] descending
Arrays.parallelSort(big);             // multi-threaded for large arrays

There is no descending sort for a primitive array — Arrays.sort(int[], Comparator) does not exist because comparators take objects. Sort ascending and read backwards, negate the values, or box to Integer[]. Sorting is stable for objects (equal elements keep their order) and, being in place on primitives, unstable in the sense that does not matter for values.

For a 2D array by a column: Arrays.sort(rows, (x, y) -> Integer.compare(x[0], y[0])); — int[][] is an array of objects, so a comparator applies.

Searching

int i = Arrays.binarySearch(sorted, 7);     // index, or -(insertionPoint) - 1 if absent; array MUST be sorted

On an unsorted array the result is meaningless. A negative return encodes where the value would go: -(r + 1) is the insertion point — useful for "first element ≥ x". For a linear search on an unsorted array there is no helper; write the loop or Arrays.asList(objs).indexOf(x) for object arrays.

Filling and creating

Arrays.fill(a, -1);                  // every element
Arrays.fill(a, 2, 5, 0);             // a range
Arrays.setAll(a, i -> i * i);        // compute each element from its index (Java 8+)
int[] sq = IntStream.range(0, 5).map(i -> i * i).toArray();   // 0 1 4 9 16

Arrays.fill on a 2D array fills the outer array with the same row reference — Arrays.fill(grid, new int[4]) makes every row the same object. Fill each row: for (int[] row : grid) Arrays.fill(row, -1);.

Copying

int[] copy = Arrays.copyOf(a, a.length);      // a full copy
int[] longer = Arrays.copyOf(a, 10);          // copied and padded with zeros — how ArrayList grows
int[] part = Arrays.copyOfRange(a, 1, 3);     // [from, to)
int[] c = a.clone();                          // also a full copy
System.arraycopy(a, 0, dest, 2, 3);           // (src, srcPos, dest, destPos, length): 3 elements from a[0] into dest[2..4]

System.arraycopy is the primitive the others are built on — a native, bulk memory copy that handles overlapping ranges correctly (so System.arraycopy(a, 0, a, 1, n - 1) shifts right in place). It throws ArrayIndexOutOfBoundsException if either range is out of bounds and ArrayStoreException for a type mismatch. All of these are shallow: for object arrays they copy references.

Converting

List<Integer> list = Arrays.asList(boxed);    // FIXED-SIZE view over the array: set() works, add()/remove() throw
List<String> l2 = Arrays.asList("a", "b");    // varargs — same fixed-size view
List<Integer> real = new ArrayList<>(Arrays.asList(boxed));   // a growable copy
List<int[]> oops = Arrays.asList(intArray);   // an int[] is ONE element — primitives are not boxed
List<Integer> ok = Arrays.stream(intArray).boxed().toList();  // the right way for int[] (Java 16 toList)
Integer[] back = list.toArray(new Integer[0]);
IntStream s = Arrays.stream(a);               // sum(), max(), filter(), … (Module 15)
int sum = Arrays.stream(a).sum();
int max = Arrays.stream(a).max().getAsInt();

Two traps in asList: it is a view backed by the array (changes go both ways; size cannot change), and it does not box primitive arrays — Arrays.asList(new int[]{1,2}) is a list with one element, the array. List.of(...) (Java 9) is the immutable alternative and rejects nulls.

Streams over arrays (a preview)

Arrays.stream(a) opens the door to sum, average, max, filter, map, sorted, distinct, anyMatch — one-liners for many loop patterns. Module 15 covers streams; until then, Arrays.stream(a).sum() and .max().getAsInt() are safe to use as vocabulary.

Utility methods you will write yourself

The JDK has no Arrays.reverse, Arrays.max for int[] (outside streams), Arrays.indexOf, Arrays.contains or Arrays.swap. They are five-line helpers; in interviews write them, in projects keep them in a small util class or use a library like Guava/Commons.

Interview angle

  • "How do you sort an int[] descending?" No comparator on primitives: sort ascending and reverse, or box.
  • "Arrays.asList(new int[]{1,2}).size()?" 1.
  • "What does Arrays.binarySearch return when the value is absent?" -(insertionPoint) - 1.
  • "Difference between Arrays.copyOf and System.arraycopy?" copyOf allocates a new array of a given length; arraycopy copies into an existing one and can overlap.
  • "Can you add to Arrays.asList?" No — UnsupportedOperationException; wrap in new ArrayList<>(…).

Key takeaways

  • Arrays.toString/equals/hashCode for contents; the array's own methods are identity-based.
  • Arrays.sort (no descending for primitives), binarySearch (sorted only, negative = insertion point), fill, setAll.
  • copyOf/copyOfRange/clone/System.arraycopy — all shallow; arraycopy handles overlap.
  • Arrays.asList is a fixed-size view and does not box primitives; Arrays.stream for int[].

Common questions

How do you print an array in Java?

Call Arrays.toString(a), which gives [3, 1, 2], or Arrays.deepToString for nested arrays. Printing the array itself uses Object.toString and shows a type code and hash such as [I@1b6d3586 instead of the contents.

How do you sort an int array in descending order in Java?

There is no descending sort for a primitive array, because Arrays.sort accepts a Comparator only for object arrays. Sort ascending and read or reverse it backwards, negate the values, or box to Integer[] and call Arrays.sort(boxed, Collections.reverseOrder()).

Why does add on Arrays.asList throw UnsupportedOperationException?

Arrays.asList returns a fixed-size view backed by the array: set works and writes through to the array, but add and remove would change its size. Wrap it in new ArrayList<>(Arrays.asList(...)) for a growable copy. It also does not box primitives, so an int[] becomes one element.

What is the difference between Arrays.copyOf and System.arraycopy?

Arrays.copyOf allocates and returns a new array of the length you give, padded with defaults or truncated. System.arraycopy(src, srcPos, dest, destPos, length) copies into an existing array and handles overlapping ranges correctly. Both are shallow copies.

What does Arrays.binarySearch return if the element is not found?

It returns -(insertionPoint) - 1, a negative number that encodes where the value would go to keep the array sorted. The array must already be sorted; on an unsorted array the result is meaningless.

Exercises

Sort, search, slice

Read an integer n, then n integers, then an integer q and q query values. Sort the array with Arrays.sort and print it with Arrays.toString. For each query print <value> at <index> if Arrays.binarySearch finds it, otherwise <value> insert at <position> where position is decoded from the negative return value. Finally print the middle third of the sorted array (Arrays.copyOfRange from n/3 to 2n/3) with Arrays.toString.

Example: 6 then 5 3 9 1 7 3, 2 then 7 4 →

[1, 3, 3, 5, 7, 9]
7 at 4
4 insert at 3
[3, 5]

Binary search report

Read an integer n, n integers, then q and q query values. Sort the array with Arrays.sort and print sorted=<Arrays.toString>. For each query print <v>: found at <index> when Arrays.binarySearch finds it, or <v>: insert at <position> decoded from the negative result (-(insertion point) - 1). Finally print equalToCopy=<Arrays.equals(sorted, Arrays.copyOf(sorted, n))>.

Example: 4 then 9 2 7 4, 3 then 7 5 10 →

sorted=[2, 4, 7, 9]
7: found at 2
5: insert at 2
10: insert at 4
equalToCopy=true

In this module: Arrays

← Two-dimensional and jagged arrays · Aliasing, shallow copies and defensive copies →