# Arrays

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Reference Types
Source: https://www.devtutorials.ai/learn/java/reference-types/arrays

> Store many values in one array, read and update elements, loop with for and for-each, build 2D and jagged arrays, and sort, search, fill and copy with the Arrays class.

Think about an egg tray.

It has a fixed number of slots in a row. Every slot holds the same kind of thing: one egg. You can point to any slot by its position, such as the third one.

An array works the same way. It is a row of slots in memory. Every slot holds a value of the same type, and each slot has a number.

In simple words: an array stores many values of one type under one name, and you reach each value by its position.

## What You Will Learn

In this lesson, you will learn:

1. Why arrays are useful and how to create one.
2. How to read and change a value by its index.
3. How to find an array's length.
4. How to visit every value with a `for` loop and a for-each loop.
5. How to build tables with two-dimensional arrays.
6. How jagged arrays let each row have a different length.
7. How to sort, search, fill, and copy arrays with the `Arrays` class.

## Start With a Working Example

Press **Run**.

```java runnable title="Five marks stored under one name"
public class Main {
    public static void main(String[] args) {
        int[] marks = {72, 85, 90, 64, 78};

        int total = 0;
        for (int mark : marks) {
            total += mark;
        }

        System.out.println("Number of marks: " + marks.length);
        System.out.println("Total: " + total);
        System.out.println("First mark: " + marks[0]);
    }
}
```

Expected output:

```text
Number of marks: 5
Total: 389
First mark: 72
```

One variable, `marks`, holds all five values. A loop visits each one to build the total.

### Try This

Add a sixth mark, `88`, inside the braces. Run it again. The count and the total both update, and you changed nothing else.

## Introduction to Arrays

An **array** is a fixed-size container that holds many values of the **same type**.

Without arrays, five marks would need five variables: `mark1`, `mark2`, `mark3`, and so on. A hundred marks would need a hundred variables. You could not loop over them, because each one has a different name.

An array solves this. All the values share one name, and a loop can visit them one by one.

Three facts about every Java array:

- **Same type.** An `int[]` holds only `int` values. A `String[]` holds only strings.
- **Fixed size.** Once created, an array cannot grow or shrink.
- **Numbered slots.** Each slot has an **index**, and the first index is `0`.

## Array Declaration and Initialization

### Declaration

**Declaring** an array creates a variable that can point to an array. You put `[]` after the type.

```text
int[] scores;
String[] names;
```

This does not create the array yet. It only creates the name.

### Creating an Array With new

`new` creates the array and sets its size.

```text
int[] scores = new int[5];
```

This makes an array with 5 slots. Each slot starts with a **default value**:

| Type | Default value |
|---|---|
| `int`, `long`, `short`, `byte` | `0` |
| `double`, `float` | `0.0` |
| `boolean` | `false` |
| `char` | an empty character (code `0`) |
| `String` and other objects | `null` |

### Initializing With Values

If you already know the values, list them inside curly braces. Java counts them and sets the size for you.

```text
String[] days = {"Mon", "Tue", "Wed"};
```

```java runnable title="Two ways to create an array"
public class Main {
    public static void main(String[] args) {
        int[] scores = new int[3];
        String[] cities = {"Chennai", "Delhi", "Pune"};

        System.out.println(scores[0] + ", " + scores[1] + ", " + scores[2]);
        System.out.println(cities[0] + ", " + cities[1] + ", " + cities[2]);
    }
}
```

Expected output:

```text
0, 0, 0
Chennai, Delhi, Pune
```

`scores` was made with `new`, so every slot holds the default `0`. `cities` was filled with values straight away.

Java also accepts `int scores[]`, with the brackets after the name. It works, but `int[] scores` is the standard style. It keeps the whole type, `int[]`, in one place.

## Accessing Elements

Each value in an array is called an **element**. You read an element with its index inside square brackets.

```text
cities[0]   // the first element
cities[2]   // the third element
```

The index always starts at `0`. So the last index is always one less than the size.

```text
Index:    0          1         2
        ┌──────────┬─────────┬────────┐
cities  │ "Chennai"│ "Delhi" │ "Pune" │
        └──────────┴─────────┴────────┘
```

Think of floors in many buildings. The ground floor is floor 0, and the floor above it is floor 1.

## Updating Elements

You change an element by assigning a new value to its index.

```java runnable title="Read and change an element by its index"
public class Main {
    public static void main(String[] args) {
        String[] tasks = {"Buy milk", "Pay bill", "Call Ravi"};

        System.out.println("Task 2 was: " + tasks[1]);

        tasks[1] = "Pay electricity bill";
        System.out.println("Task 2 is now: " + tasks[1]);

        int[] stock = {10, 4, 7};
        stock[2] = stock[2] - 3;
        System.out.println("Stock left in slot 2: " + stock[2]);
    }
}
```

Expected output:

```text
Task 2 was: Pay bill
Task 2 is now: Pay electricity bill
Stock left in slot 2: 4
```

`tasks[1]` is the second task, because counting starts at `0`.

`stock[2] = stock[2] - 3` reads the old value, takes 3 away, and stores the answer back in the same slot.

## Array Length

Every array knows its own size. You read it with `.length`.

```text
int[] marks = {72, 85, 90};
marks.length   // 3
```

`length` has no brackets, because it is a property, not a method. This is different from a `String`, where you write `name.length()`.

The last index is always `length - 1`. Reading `marks[marks.length]` goes one step past the end.

```java runnable expect-error title="Arrays use length, not length()"
public class Main {
    public static void main(String[] args) {
        int[] marks = {72, 85, 90};
        System.out.println(marks.length());
    }
}
```

The compiler reports `cannot find symbol`, because arrays have no `length()` method.

Reading an index that does not exist, such as `marks[3]` in a 3-element array, compiles fine. But when the program runs, it stops with an `ArrayIndexOutOfBoundsException`. Valid indexes go from `0` to `length - 1`.

## Single-Dimensional Arrays

A **single-dimensional** array is a plain row of values, like every array so far.

### Array Traversal

**Traversing** an array means visiting every element, one after another.

The usual way is a `for` loop that counts the index from `0` up to `length - 1`.

```java runnable title="A for loop visits every index"
public class Main {
    public static void main(String[] args) {
        double[] prices = {120.0, 45.5, 300.0, 89.0};

        double highest = prices[0];
        for (int i = 0; i < prices.length; i++) {
            System.out.println("Item " + i + ": " + prices[i]);
            if (prices[i] > highest) {
                highest = prices[i];
            }
        }

        System.out.println("Highest price: " + highest);
    }
}
```

Expected output:

```text
Item 0: 120.0
Item 1: 45.5
Item 2: 300.0
Item 3: 89.0
Highest price: 300.0
```

Starting `highest` at `prices[0]` gives the loop something to compare against. Each bigger value replaces it.

A `for` loop with an index is the right choice when you need the position, or when you want to change elements.

### foreach

The **for-each** loop is a shorter way to visit every element. It hands you each value in turn, with no index to manage.

```text
for (type item : array) {
    // use item
}
```

Read the `:` as "in". So `for (String name : names)` means "for each name in names".

```java runnable title="for-each reads every value without an index"
public class Main {
    public static void main(String[] args) {
        String[] guests = {"Asha", "Ravi", "Meena", "Arjun"};

        for (String guest : guests) {
            System.out.println("Welcome, " + guest);
        }
    }
}
```

Expected output:

```text
Welcome, Asha
Welcome, Ravi
Welcome, Meena
Welcome, Arjun
```

There is no `i`, no `length`, and no `[ ]`. That leaves nothing to get wrong.

### for vs for-each

The for-each variable holds a **copy** of each value. Changing it does not change the array.

```java runnable title="for-each cannot change the array, but for can"
public class Main {
    public static void main(String[] args) {
        int[] points = {10, 20, 30};

        for (int p : points) {
            p = p * 2;
        }
        System.out.println("After for-each: " + points[0] + ", " + points[1] + ", " + points[2]);

        for (int i = 0; i < points.length; i++) {
            points[i] = points[i] * 2;
        }
        System.out.println("After for:      " + points[0] + ", " + points[1] + ", " + points[2]);
    }
}
```

Expected output:

```text
After for-each: 10, 20, 30
After for:      20, 40, 60
```

The for-each loop only doubled its own copy, `p`. The indexed `for` loop wrote back into `points[i]`, so the array changed.

| | `for` with index | for-each |
|---|---|---|
| Gives you the index? | Yes | No |
| Can change array elements? | Yes | No |
| Can go backwards or skip items? | Yes | No |
| Risk of an index mistake | Yes | None |
| Best for | Changing values, using positions | Reading every value |

## Multidimensional Arrays

A **multidimensional array** is an array of arrays. The most common kind is **two-dimensional (2D)**: a table with rows and columns.

Think of a cinema seating plan. You find a seat with two numbers: the row and the seat in that row.

You use two pairs of brackets:

```text
int[][] grid = new int[3][4];   // 3 rows, 4 columns
grid[1][2] = 9;                 // row 1, column 2
```

You can also fill it with values. Each inner `{ }` is one row:

```text
int[][] marks = {
    {80, 75, 90},
    {65, 70, 85}
};
```

### Traversing Multidimensional Arrays

To visit every cell, use a nested loop. The outer loop picks the row. The inner loop walks along the columns of that row.

```java runnable title="Nested for loops visit every row and column"
public class Main {
    public static void main(String[] args) {
        int[][] marks = {
            {80, 75, 90},
            {65, 70, 85}
        };
        String[] students = {"Asha", "Ravi"};

        for (int row = 0; row < marks.length; row++) {
            int total = 0;
            for (int col = 0; col < marks[row].length; col++) {
                total += marks[row][col];
            }
            System.out.println(students[row] + " total: " + total);
        }

        System.out.println("Ravi's second subject: " + marks[1][1]);
    }
}
```

Expected output:

```text
Asha total: 245
Ravi total: 220
Ravi's second subject: 70
```

`marks.length` is the number of rows, `2`. `marks[row].length` is the number of columns in that row, `3`.

`marks[1][1]` means row 1, column 1. That is Ravi's second mark.

### Nested foreach Loops

Nested for-each loops are shorter when you only need to read the values.

The outer loop gives you each row, which is itself an array. The inner loop gives you each value in that row.

```java runnable title="Nested for-each loops print a seating grid"
public class Main {
    public static void main(String[] args) {
        char[][] seats = {
            {'O', 'X', 'O'},
            {'X', 'X', 'O'},
            {'O', 'O', 'O'}
        };

        int free = 0;
        for (char[] row : seats) {
            for (char seat : row) {
                System.out.print(seat + " ");
                if (seat == 'O') {
                    free++;
                }
            }
            System.out.println();
        }
        System.out.println("Free seats: " + free);
    }
}
```

Expected output:

```text
O X O
X X O
O O O
Free seats: 6
```

The outer variable has the type `char[]`, because each row is an array of `char`. The inner variable has the type `char`.

## Jagged Arrays

In a **jagged array**, each row can have a different length.

This works because a 2D array is really an array of separate arrays. Nothing forces them to be the same size.

Think of a week of class timetables. Monday has 3 classes, Tuesday has 1, and Wednesday has 4.

To make one, give only the number of rows. Then create each row with its own size.

```java runnable title="Each row of a jagged array has its own length"
public class Main {
    public static void main(String[] args) {
        String[][] classes = new String[3][];
        classes[0] = new String[] {"Maths", "English", "Science"};
        classes[1] = new String[] {"Art"};
        classes[2] = new String[] {"History", "Maths", "PE", "Music"};

        String[] days = {"Mon", "Tue", "Wed"};

        for (int d = 0; d < classes.length; d++) {
            System.out.print(days[d] + " (" + classes[d].length + "): ");
            for (String subject : classes[d]) {
                System.out.print(subject + " ");
            }
            System.out.println();
        }
    }
}
```

Expected output:

```text
Mon (3): Maths English Science
Tue (1): Art
Wed (4): History Maths PE Music
```

`new String[3][]` creates 3 empty row slots. Each row is then set to its own array.

Always use `classes[d].length` for the inner loop. A fixed number like `3` would fail on the shorter and longer rows.

## Arrays Utility Class

Java has a ready-made class called `Arrays` with useful methods for working with arrays.

It lives in `java.util`, so you import it at the top of the file:

```text
import java.util.Arrays;
```

All its methods are `static`, so you call them on the class: `Arrays.sort(numbers)`.

`Arrays.toString()` is handy too. It turns an array into readable text, like `[3, 1, 2]`. Printing an array directly only shows a code such as `[I@1b6d3586`.

### sort()

`Arrays.sort()` puts the elements in order, smallest first. Strings are sorted alphabetically.

It changes the array itself. It does not return a new one.

### binarySearch()

`Arrays.binarySearch()` finds a value and returns its index.

It is very fast, but it only works on a **sorted** array. On an unsorted array, the answer can be wrong.

If the value is not found, it returns a negative number.

### fill()

`Arrays.fill()` sets every element to the same value.

### copyOf()

`Arrays.copyOf()` returns a **new** array with a size you choose.

- A smaller size cuts off the extra elements.
- A bigger size adds default values, such as `0`, at the end.

This is how you grow an array: make a bigger copy.

```java runnable title="sort, binarySearch, fill and copyOf"
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] ages = {34, 19, 52, 27, 41};

        Arrays.sort(ages);
        System.out.println("Sorted: " + Arrays.toString(ages));

        int position = Arrays.binarySearch(ages, 41);
        System.out.println("41 is at index " + position);
        System.out.println("60 found? " + (Arrays.binarySearch(ages, 60) >= 0));

        int[] scores = new int[4];
        Arrays.fill(scores, 100);
        System.out.println("Filled: " + Arrays.toString(scores));

        int[] firstThree = Arrays.copyOf(ages, 3);
        int[] bigger = Arrays.copyOf(ages, 7);
        System.out.println("First three: " + Arrays.toString(firstThree));
        System.out.println("Bigger: " + Arrays.toString(bigger));
    }
}
```

Expected output:

```text
Sorted: [19, 27, 34, 41, 52]
41 is at index 3
60 found? false
Filled: [100, 100, 100, 100]
First three: [19, 27, 34]
Bigger: [19, 27, 34, 41, 52, 0, 0]
```

After sorting, `41` sits at index 3. `60` is not in the array, so `binarySearch` returns a negative number.

`copyOf(ages, 7)` makes a new array of 7 slots. The two extra slots get the default value `0`. The original `ages` array is unchanged.

| Method | What it does | Changes the original? |
|---|---|---|
| `Arrays.sort(a)` | Puts the elements in order | Yes |
| `Arrays.binarySearch(a, v)` | Returns the index of `v`, or a negative number | No |
| `Arrays.fill(a, v)` | Sets every element to `v` | Yes |
| `Arrays.copyOf(a, n)` | Returns a new array of size `n` | No |
| `Arrays.toString(a)` | Returns the elements as text, like `[1, 2, 3]` | No |

**Easy Way to Remember:** sort before you search. `binarySearch` only gives a correct answer on a sorted array.

## Common mistakes

The following mistakes are common when working with arrays. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| The second item prints instead of the first | The code starts at index 1 | Start at index 0 |
| `ArrayIndexOutOfBoundsException` | An index of `length` or more was used | Loop with `i < array.length` |
| Output like `[I@1b6d3586` | The array was printed directly | Use `Arrays.toString(array)` |
| Values do not change after a loop | A for-each copy was changed | Use an indexed `for` loop |
| `cannot find symbol` on `length()` | Brackets were added to `length` | Write `array.length` |
| `binarySearch` gives a strange index | The array was not sorted | Call `Arrays.sort` first |

## What to Remember

- An array holds a fixed number of values of one type. The first index is `0`, and the last is `length - 1`.
- Create an array with `new int[5]` or with values in braces: `{1, 2, 3}`.
- Read and change elements with `array[index]`. Get the size with `array.length`, with no brackets.
- Use an indexed `for` loop to change values. Use for-each to read them.
- A 2D array is an array of arrays. A jagged array's rows can have different lengths.
- `Arrays.sort`, `binarySearch`, `fill`, `copyOf`, and `toString` handle common array jobs. Sort before you search.

Next: Strings
