☕ Java

One-Dimensional Array

A one-dimensional array is a linear sequence of elements of the same type, accessed by a single integer index. It is the simplest array form in Java and the foundation for understanding multidimensional arrays and collection classes. One-dimensional arrays are used to store and process lists of values — student grades, product prices, daily temperatures, character sequences — any time you need to work with a fixed-size ordered collection of homogeneous data.

Creating and Traversing One-Dimensional Arrays

The for loop and the enhanced for-each loop are the two primary ways to traverse a one-dimensional array. The traditional for loop with an explicit index variable gives access to the index itself — essential when you need to know the position of each element, when you need to modify elements in place, when you process the array in reverse, or when you compare elements at two indices simultaneously. The enhanced for-each loop is cleaner and less error-prone for pure read traversal where the index is not needed, because it eliminates the possibility of off-by-one errors in the loop condition. A critical difference to understand is that the for-each loop cannot modify primitive array elements. When you write for (int n : numbers) and then n = 99, you are assigning to the local copy n — the array element is unchanged. Modifying the array during traversal requires either the traditional for loop with an index, or traversal and construction of a new array with the modified values. For reference arrays, you can call mutating methods on the referenced objects through the for-each loop, but you cannot replace the array element with a different object reference. Both loop forms are O(n) — they visit each element exactly once. The choice between them is entirely about readability and whether you need the index. When you do not need the index, for-each is preferred by convention.
Java
// ── Creating a one-dimensional array: ────────────────────────────────
int[] temperatures = {22, 25, 19, 28, 31, 24, 20};
System.out.println("Days of data: " + temperatures.length);  // 7

// ── Traditional for loop — access by index: ───────────────────────────
System.out.println("Traditional for loop:");
for (int i = 0; i < temperatures.length; i++) {
    System.out.printf("  Day %d: %d°C%n", i + 1, temperatures[i]);
}

// ── Enhanced for-each loop — cleaner for reading: ─────────────────────
System.out.println("For-each loop:");
for (int temp : temperatures) {
    System.out.println("  " + temp + "°C");
}

// ── For-each CANNOT modify primitive array elements: ─────────────────
int[] values = {1, 2, 3, 4, 5};
for (int v : values) {
    v = v * 2;          // assigns to LOCAL variable v — array unchanged!
}
System.out.println(Arrays.toString(values));  // [1, 2, 3, 4, 5] — unchanged

// To modify, use indexed loop:
for (int i = 0; i < values.length; i++) {
    values[i] = values[i] * 2;   // modifies the array element directly
}
System.out.println(Arrays.toString(values));  // [2, 4, 6, 8, 10]

// ── Traversal in reverse: ─────────────────────────────────────────────
int[] countdown = {5, 4, 3, 2, 1};
for (int i = countdown.length - 1; i >= 0; i--) {
    System.out.print(countdown[i] + " ");   // 1 2 3 4 5
}
System.out.println();

// ── Skip every other element: ────────────────────────────────────────
int[] everyOther = {10, 20, 30, 40, 50, 60};
for (int i = 0; i < everyOther.length; i += 2) {
    System.out.print(everyOther[i] + " ");  // 10 30 50
}

Common Array Operations

Several operations on one-dimensional arrays appear so frequently that every Java developer should know their efficient implementations by heart: finding the sum and average, finding the minimum and maximum, counting elements that satisfy a condition, reversing an array, and linear search. These are the building blocks from which more complex algorithms are assembled. Finding the minimum and maximum requires a linear scan — visit every element at least once and track the current best. The initial value for the running min or max should be the first element of the array, not a hardcoded value like Integer.MAX_VALUE, because using the first element is type-agnostic and correct regardless of the actual value range. The array must have at least one element; checking length > 0 before performing these operations prevents ArrayIndexOutOfBoundsException. Reversing an array in place uses the two-pointer technique: maintain a left index starting at 0 and a right index starting at length-1, swap the elements at these positions, and advance the left pointer forward and the right pointer backward until they meet in the middle. This is O(n) time and O(1) space — no new array is needed. Understanding this technique is foundational for many other array manipulation algorithms.
Java
// ── Sum and average: ─────────────────────────────────────────────────
int[] grades = {88, 92, 79, 95, 84, 91, 76, 88};

int sum = 0;
for (int grade : grades) {
    sum += grade;
}
double average = (double) sum / grades.length;
System.out.printf("Sum: %d, Average: %.1f%n", sum, average);
// Sum: 693, Average: 86.6

// ── Find minimum and maximum: ─────────────────────────────────────────
int min = grades[0];
int max = grades[0];

for (int i = 1; i < grades.length; i++) {
    if (grades[i] < min) min = grades[i];
    if (grades[i] > max) max = grades[i];
}
System.out.printf("Min: %d, Max: %d, Range: %d%n", min, max, max - min);
// Min: 76, Max: 95, Range: 19

// ── Count elements satisfying a condition: ────────────────────────────
int passCount = 0;
for (int grade : grades) {
    if (grade >= 80) passCount++;
}
System.out.printf("%d of %d students passed (%.0f%%)%n",
    passCount, grades.length, (double) passCount / grades.length * 100);

// ── Reverse array in place — two-pointer technique: ───────────────────
int[] arr = {1, 2, 3, 4, 5, 6, 7};
int left = 0, right = arr.length - 1;
while (left < right) {
    int temp   = arr[left];
    arr[left]  = arr[right];
    arr[right] = temp;
    left++;
    right--;
}
System.out.println(Arrays.toString(arr));  // [7, 6, 5, 4, 3, 2, 1]

// ── Linear search: ────────────────────────────────────────────────────
public static int linearSearch(int[] array, int target) {
    for (int i = 0; i < array.length; i++) {
        if (array[i] == target) return i;   // found — return index
    }
    return -1;                               // not found
}

int[] data = {14, 27, 3, 89, 42, 55, 8};
System.out.println(linearSearch(data, 42));  // 4
System.out.println(linearSearch(data, 99));  // -1

// ── Copying an array (not reference copy): ────────────────────────────
int[] source = {10, 20, 30, 40, 50};

// BUG — reference copy, not element copy:
int[] alias  = source;          // alias and source point to SAME array
alias[0]     = 99;
System.out.println(source[0]);  // 99 — source changed through alias!

// CORRECT — element copy:
int[] copy1 = Arrays.copyOf(source, source.length);
int[] copy2 = new int[source.length];
System.arraycopy(source, 0, copy2, 0, source.length);

Passing Arrays to Methods and Returning Arrays

Arrays are objects in Java, so when you pass an array to a method, you pass the reference — not a copy of the data. This means the method receives access to the same underlying array and can modify its elements. Changes made to the array inside the method are visible to the caller after the method returns. This behaviour is called pass-by-reference for arrays (though Java technically always passes references by value — the distinction is subtle but the practical effect is that array modifications persist). This has an important consequence: if a method should not modify the caller's array, it must work on a copy. The caller can make the copy before passing, or the method can make the copy at the start of its body. Neither Java nor the compiler enforces this — the programmer must be deliberate about whether method-side modifications should be visible to the caller. Returning an array from a method is straightforward — the return type declares the array type, and the method returns a reference. The returned array can be a newly created array, a copy of an existing one, or an array that was passed in and modified. Returning a zero-length array (new int[0] or new int[]{}) is the preferred alternative to returning null when no results exist — it eliminates null checks in the caller and is consistent with the principle that methods should return empty collections rather than null for absent results.
Java
// ── Method receiving and modifying an array: ─────────────────────────
public static void doubleAll(int[] array) {
    for (int i = 0; i < array.length; i++) {
        array[i] *= 2;      // modifies the caller's array
    }
}

int[] values = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(values));  // [1, 2, 3, 4, 5]
doubleAll(values);
System.out.println(Arrays.toString(values));  // [2, 4, 6, 8, 10] — changed!

// ── Method that should NOT modify its argument — work on a copy: ──────
public static int[] doubledCopy(int[] array) {
    int[] result = new int[array.length];       // new array — original safe
    for (int i = 0; i < array.length; i++) {
        result[i] = array[i] * 2;
    }
    return result;
}

int[] original = {1, 2, 3, 4, 5};
int[] doubled  = doubledCopy(original);
System.out.println(Arrays.toString(original));  // [1, 2, 3, 4, 5] — unchanged
System.out.println(Arrays.toString(doubled));   // [2, 4, 6, 8, 10]

// ── Returning an array from a method: ────────────────────────────────
public static int[] range(int start, int end) {
    if (start > end) return new int[0];   // empty array — not null
    int[] result = new int[end - start + 1];
    for (int i = 0; i < result.length; i++) {
        result[i] = start + i;
    }
    return result;
}

System.out.println(Arrays.toString(range(1, 10)));   // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(Arrays.toString(range(5, 5)));    // [5]
System.out.println(Arrays.toString(range(10, 1)));   // []

// ── Varargs — method accepting variable number of array arguments: ─────
public static int sum(int... numbers) {
    // numbers is a regular int[] inside the method
    int total = 0;
    for (int n : numbers) total += n;
    return total;
}

System.out.println(sum(1, 2, 3));           // 6 — three args
System.out.println(sum(1, 2, 3, 4, 5));    // 15 — five args
System.out.println(sum());                  // 0  — zero args
int[] arr = {10, 20, 30};
System.out.println(sum(arr));               // 60 — existing array

Related Topics in Arrays

Array Basics
An array in Java is a fixed-size, ordered collection of elements of the same type stored in a contiguous block of memory. Once created, the size of an array cannot change. Arrays are the simplest and most fundamental data structure in Java — they underlie many higher-level collections and provide direct, indexed access to elements in constant time O(1). Every array in Java is an object, inherits from java.lang.Object, and can hold either primitives or references.
Two-Dimensional Array
A two-dimensional array in Java is an array of arrays — each element of the outer array is itself a one-dimensional array. It is used to represent tabular data with rows and columns: matrices, game boards, spreadsheet grids, pixel buffers, and any data that is naturally organised in two dimensions. In Java, a 2D array is declared with two sets of brackets and accessed with two indices: array[row][column].
Multidimensional Array
A multidimensional array in Java is an array with more than two dimensions — an array of arrays of arrays, and so on. While two-dimensional arrays suffice for most programming tasks, three-dimensional arrays are used for spatial data (x, y, z coordinates of a 3D grid), volumetric data (layers, rows, columns), RGB pixel buffers, and scientific computations involving tensors. Java supports arbitrary dimensionality, though arrays beyond three dimensions are rare in practice.
Jagged Array
A jagged array (also called a ragged array) is a multidimensional array where the inner arrays have different lengths. Unlike a rectangular 2D array where every row has the same number of columns, a jagged array allows each row to have its own independently sized inner array. This is possible because Java implements multidimensional arrays as arrays of arrays, making each inner array an independent object that can have any length.