Arrays in Java

By the Syncfusion DevTutorials team · Last updated

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.

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:

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.

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.

int[] scores = new int[5];

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

TypeDefault value
int, long, short, byte0
double, float0.0
booleanfalse
charan empty character (code 0)
String and other objectsnull

Initializing With Values

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

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

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:

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.

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.

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.

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:

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.

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.

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.

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:

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.

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

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

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:

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.

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:

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 indexfor-each
Gives you the index?YesNo
Can change array elements?YesNo
Can go backwards or skip items?YesNo
Risk of an index mistakeYesNone
Best forChanging values, using positionsReading 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:

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:

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.

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:

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.

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:

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.

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:

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:

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.

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:

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.

MethodWhat it doesChanges the original?
Arrays.sort(a)Puts the elements in orderYes
Arrays.binarySearch(a, v)Returns the index of v, or a negative numberNo
Arrays.fill(a, v)Sets every element to vYes
Arrays.copyOf(a, n)Returns a new array of size nNo
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.

SymptomCauseFix
The second item prints instead of the firstThe code starts at index 1Start at index 0
ArrayIndexOutOfBoundsExceptionAn index of length or more was usedLoop with i < array.length
Output like [I@1b6d3586The array was printed directlyUse Arrays.toString(array)
Values do not change after a loopA for-each copy was changedUse an indexed for loop
cannot find symbol on length()Brackets were added to lengthWrite array.length
binarySearch gives a strange indexThe array was not sortedCall 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