FirstHack Learn
Log in Sign up free

Arrays and Strings

9 min read · 43 views

Arrays and Strings

Arrays and strings are the two collections you will use in almost every exercise this year. Java handles both quite differently from C, and mostly more safely.

Arrays

An array holds a fixed number of values of one type, stored together and reached by index. Indexing starts at 0, so an array of five elements has valid indices 0 through 4.

Java arrays differ from C arrays in two important ways. They are objects, created with new and reached through a reference. And they know their own length, exposed as the field length.

Java
public class Main {
    public static void main(String[] args) {
        int[] marks = {78, 65, 92, 41, 88};

        int[] scores = new int[5];
        scores[0] = 50;
        scores[1] = 60;

        System.out.println("Length: " + marks.length);
        System.out.println("First:  " + marks[0]);
        System.out.println("Last:   " + marks[marks.length - 1]);

        System.out.println("Default value in a new int array: " + scores[4]);

        int total = 0;
        int highest = marks[0];
        for (int i = 0; i < marks.length; i++) {
            total += marks[i];
            if (marks[i] > highest) {
                highest = marks[i];
            }
        }
        System.out.println("Total:   " + total);
        System.out.println("Highest: " + highest);
        System.out.printf("Average: %.2f%n", (double) total / marks.length);

        String[] subjects = {"Maths", "Physics", "Chemistry"};
        for (String s : subjects) {
            System.out.println("- " + s);
        }

        int[][] grid = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        for (int[] row : grid) {
            for (int cell : row) {
                System.out.print(cell + " ");
            }
            System.out.println();
        }
    }
}

Three details from that program.

marks.length is a field, not a method. There are no brackets. This is inconsistent with String.length(), which is a method with brackets, and mixing them up is a compile error you will make more than once.

An array made with new is filled with defaults: 0 for numeric types, false for boolean, null for object types. Unlike a local variable, it is never garbage.

The size is fixed at creation. new int[5] holds five ints forever. You cannot grow it; you would have to create a bigger array and copy across. That limitation is exactly what ArrayList solves.

ℹ️Java checks your array bounds and C does not

marks[10] on a five-element array throws ArrayIndexOutOfBoundsException naming the bad index, and the program stops immediately. The same code in C reads whatever memory happens to be there and carries on with a wrong answer. An exception with a line number is a far better outcome than silent corruption, so treat it as the language helping you rather than the language complaining.

ArrayList

ArrayList is a resizable array from java.util. It grows as you add, tracks its own size, and is the right default when you do not know the count in advance.

Because it stores objects rather than primitives, you write ArrayList<Integer> and not ArrayList<int>. Java converts between int and Integer automatically, so in practice you rarely notice.

Java
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<String> subjects = new ArrayList<>();

        subjects.add("Maths");
        subjects.add("Physics");
        subjects.add("Chemistry");
        subjects.add("English");

        System.out.println("Count: " + subjects.size());
        System.out.println("First: " + subjects.get(0));

        subjects.remove("English");
        subjects.set(1, "Applied Physics");

        for (String s : subjects) {
            System.out.println("- " + s);
        }

        System.out.println("Has Maths? " + subjects.contains("Maths"));
        System.out.println("Index of Chemistry: " + subjects.indexOf("Chemistry"));

        ArrayList<Integer> marks = new ArrayList<>();
        marks.add(78);
        marks.add(65);
        marks.add(92);

        int total = 0;
        for (int m : marks) {
            total += m;
        }
        System.out.printf("Average: %.2f%n", (double) total / marks.size());

        System.out.println("Empty? " + marks.isEmpty());
        marks.clear();
        System.out.println("After clear: " + marks.size());
    }
}

The methods you will use most:

Method Meaning
add(x) Append x at the end
get(i) The element at index i
set(i, x) Replace the element at index i
remove(i) Remove by index
size() Number of elements
contains(x) Whether x is present
isEmpty() Whether the list has no elements
clear() Remove everything

Note the mismatch again: arrays use length, ArrayList uses size(), String uses length(). There is no logic to it; it is history.

One sharp edge: on an ArrayList<Integer>, remove(2) removes the element at index 2, while remove(Integer.valueOf(2)) removes the value 2. Java picks the overload by type, which is easy to get wrong here.

Strings

A String is an object holding a sequence of characters, and it is immutable: once created, the characters can never change. Every method that looks like it modifies a string actually returns a new one.

Java
public class Main {
    public static void main(String[] args) {
        String name = "  Priya Sharma  ";

        System.out.println("[" + name + "]");
        System.out.println("[" + name.trim() + "]");
        System.out.println("Unchanged: [" + name + "]");

        String clean = name.trim();
        System.out.println("Length: " + clean.length());
        System.out.println("Upper:  " + clean.toUpperCase());
        System.out.println("Lower:  " + clean.toLowerCase());
        System.out.println("Char 0: " + clean.charAt(0));
        System.out.println("Sub:    " + clean.substring(0, 5));
        System.out.println("Index:  " + clean.indexOf("Sharma"));
        System.out.println("Starts: " + clean.startsWith("Priya"));
        System.out.println("Replace:" + clean.replace("Priya", "Meera"));

        String[] parts = clean.split(" ");
        for (String p : parts) {
            System.out.println("Part: " + p);
        }

        System.out.println("equals:        " + clean.equals("Priya Sharma"));
        System.out.println("equalsIgnore:  " + clean.equalsIgnoreCase("PRIYA SHARMA"));
        System.out.println("compareTo:     " + clean.compareTo("Priya Sharma"));

        int vowels = 0;
        for (char c : clean.toCharArray()) {
            if ("aeiouAEIOU".indexOf(c) >= 0) vowels++;
        }
        System.out.println("Vowels: " + vowels);
    }
}

Why immutability matters

It sounds like a restriction. It buys three concrete things.

Safety when sharing. If you pass a string to a method, that method cannot change it behind your back. You never have to defend against it.

Reuse. Because two identical string literals can never diverge, Java keeps one copy in an internal pool and points both at it, saving memory.

Predictability in collections. A string used as a key in a hash-based structure cannot change while it is in there, which would otherwise leave the structure unable to find its own entry.

The cost is that building a string in a loop with s = s + x creates a brand-new string every pass, copying everything each time. For a handful of pieces this is irrelevant. For thousands, use StringBuilder, which is a mutable buffer with an append method and a toString() at the end.

Common mistakes

  • array.length() or string.length. Arrays use the field length; String and ArrayList use methods length() and size().
  • Looping to i <= array.length. The last valid index is length - 1. This throws ArrayIndexOutOfBoundsException.
  • Comparing strings with ==. It compares references. Use .equals().
  • Expecting s.toUpperCase() to change s. It returns a new string. Write s = s.toUpperCase();.
  • Writing ArrayList<int>. Generics need object types: ArrayList<Integer>.
  • Confusing remove(index) and remove(object) on an ArrayList<Integer>. Wrap the value: remove(Integer.valueOf(2)).
  • Calling a method on a null array element. A new String[5] is full of nulls until you fill it.

Arrays, lists and strings cover most of the data handling in a first-year syllabus. Try reversing an array in place and counting word frequencies in a sentence, then look at the collection problems on the Practice page.

Create a free account to track what you have finished.