Arrays

Learning goals

Create and iterate arrays, understand length vs length(), copy and sort arrays, work with multi-dimensional arrays, and know when to prefer ArrayList instead.


Declaring and initializing

int[] nums = new int[5];           // five zeros
int[] primes = {2, 3, 5, 7, 11};   // array literal
String[] names = new String[] {"Ada", "Grace"};

Preferred style: int[] nums not int nums[] (C legacy).

Length is a field (not a method):

System.out.println(primes.length);  // 5

Valid indices: 0 to length - 1. Out of bounds → ArrayIndexOutOfBoundsException.


Reading and writing

primes[0] = 2;
for (int i = 0; i < primes.length; i++) {
    System.out.println(primes[i]);
}

for (int p : primes) {
    System.out.println(p);
}

Default values when using new int[n]: 0 for numeric, false for boolean, null for references.


Arrays are objects

int[] a = {1, 2, 3};
int[] b = a;       // same array
b[0] = 99;
System.out.println(a[0]);  // 99

Assignment copies the reference, not elements.


Copying arrays

int[] original = {1, 2, 3};
int[] shallow = original.clone();
int[] copy = Arrays.copyOf(original, original.length);
int[] slice = Arrays.copyOfRange(original, 1, 3);  // {2, 3}

Arrays.equals(a, b) compares element-wise for primitive arrays.


Sorting and searching

import java.util.Arrays;

int[] data = {5, 1, 4};
Arrays.sort(data);                    // {1, 4, 5}
int idx = Arrays.binarySearch(data, 4);  // 1 (must be sorted)

binarySearch returns negative insertion point - 1 if not found.


Multi-dimensional arrays

int[][] matrix = {
    {1, 2},
    {3, 4, 5}
};

matrix[1][2] = 5;
System.out.println(matrix.length);     // 2 rows
System.out.println(matrix[1].length);  // 3 cols in row 1

Java arrays of arrays are jagged—each row can have different length.


Arrays vs ArrayList

Array ArrayList<E>
Size Fixed after creation Grows dynamically
Primitives Yes (int[]) No (use Integer)
Generics No Yes
Performance Slightly faster, less overhead More flexible API
List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
list.add(4);

Use arrays for fixed-size buffers and performance-critical code; List for most application logic.


Converting to and from List

Integer[] boxed = {1, 2, 3};
List<Integer> fromArray = Arrays.asList(boxed);  // fixed-size view

List<String> mutable = new ArrayList<>(List.of("a", "b"));
String[] back = mutable.toArray(String[]::new);

List.of and Arrays.asList return immutable or fixed-size views—know before mutating.


Streams (preview)

JDK streams can process arrays without manual loops:

int sum = Arrays.stream(primes).sum();
int[] doubled = Arrays.stream(primes).map(x -> x * 2).toArray();

Full stream API is beyond this chapter; arrays integrate cleanly when needed.


Common mistakes

  1. array.length() — arrays use .length, Strings use .length().
  2. Off-by-one loopsi <= arr.length accesses invalid index.
  3. Assuming deep copyclone() on int[] is deep; on Object[] copies references only.
  4. Arrays.binarySearch on unsorted array — undefined/wrong results.
  5. Returning internal mutable array from a class — expose copies or unmodifiable lists.

Practice checkpoint

  1. Create int[3] and fill with squares 1, 4, 9.

    • Answer: int[] sq = {1, 4, 9}; or loop sq[i] = (i+1)*(i+1).
  2. What is default value of new String[2][1] elements?

    • Answer: null
  3. Find index of 7 in sorted {1,3,5,7,9} with binarySearch.

    • Answer: 3
  4. Why might int[] beat ArrayList<Integer> in a tight numeric loop?

    • Answer: No boxing/unboxing, better cache locality, less allocation.

Interview angles

  • “Array on heap or stack?” — Array object on heap; reference variable in stack frame (like all objects).
  • “Can you resize an array?” — No; allocate new array and copy.
  • “equals on arrays?”== compares references; use Arrays.equals or Arrays.deepEquals for nested.

Next: /java/learn/language/strings/