jario_
Back to overview

Chapter 5

Strings

You've used text since chapter 1. But a String can do more than be printed: it knows its length, you can cut out pieces, search for characters and go through it character by character. You call these methods with a dot: text.length().

Length, pieces, searching

The most important methods:

  • length(): number of characters
  • charAt(i): the character at position i, counted from 0 like arrays
  • substring(start, end): the piece from start up to before end; substring(start) takes everything to the end
  • indexOf('@'): position of the first match, -1 if there is none
  • contains("Java"): true if the piece occurs
  • toUpperCase(), toLowerCase(): all upper or lower case
  • trim(): removes spaces at the start and end

A string can't be changed. All these methods return a new string, the old one stays as it was. That's why the last line prints Hello, Java! again.

public class Main {
    public static void main(String[] args) {
        String text = "  Hello, Java!  ";
        String clean = text.trim();
        System.out.println("[" + clean + "]");
        System.out.println("Length: " + clean.length());
        System.out.println("First: " + clean.charAt(0));
        System.out.println("Last: " + clean.charAt(clean.length() - 1));

        System.out.println(clean.substring(0, 5));
        System.out.println(clean.substring(7));
        System.out.println(clean.indexOf(','));
        System.out.println(clean.indexOf('x'));
        System.out.println(clean.contains("Java"));

        System.out.println(clean.toUpperCase());
        System.out.println(clean);
    }
}

Character by character

A single character has the type char and goes in single quotes: 'a'. You compare characters with ==. With a for loop from 0 to length() - 1 and charAt(i) you go through a text character by character.

There are ready-made checks for single characters: Character.isDigit(c), Character.isLetter(c) and Character.isUpperCase(c).

Behind every char is a number, and the letters are in order. So you can calculate with them: 'c' - 'a' is 2. The result is an int. Put (char) in front to turn it back into a character.

public class Main {
    public static void main(String[] args) {
        String password = "Secret42";
        int digits = 0;
        int upperCase = 0;
        for (int i = 0; i < password.length(); i++) {
            char c = password.charAt(i);
            if (Character.isDigit(c)) {
                digits++;
            }
            if (Character.isUpperCase(c)) {
                upperCase++;
            }
        }
        System.out.println("Digits: " + digits);
        System.out.println("Upper case: " + upperCase);

        char letter = 'c';
        int position = letter - 'a';
        System.out.println(letter + " is letter number " + (position + 1));
        char next = (char) (letter + 1);
        System.out.println("After " + letter + " comes " + next);
    }
}

Splitting and building

split(" ") splits a text at every space and returns a String[] with the parts. You loop over it like any array.

You can build a result text piece by piece with +=. With many parts, a StringBuilder is better: append(...) adds to the end, toString() returns the finished string.

public class Main {
    public static void main(String[] args) {
        String sentence = "Java is fun";
        String[] words = sentence.split(" ");
        System.out.println(words.length + " words");

        String initials = "";
        for (String word : words) {
            initials += word.charAt(0);
        }
        System.out.println(initials);

        StringBuilder sb = new StringBuilder();
        for (int i = words.length - 1; i >= 0; i--) {
            sb.append(words[i]);
            if (i > 0) {
                sb.append(" ");
            }
        }
        System.out.println(sb.toString());
    }
}

Common mistakes

  • Comparing strings with ==

    == checks whether two variables point to the same object, not whether the letters are equal. With text that was read in or put together, that's often false:

    String a = "Java";
    String b = "Ja";
    b += "va";
    System.out.println(a == b);      // false
    System.out.println(a.equals(b)); // true

    Always compare text with equals. Only single char values are compared with ==.

  • Result not stored

    name.toUpperCase(); on its own changes nothing, because strings can't be changed. You have to store the result: name = name.toUpperCase();.

  • length, length() or size()?

    For an array it's numbers.length without parentheses, for a string text.length() with parentheses. Mix them up and the compiler reports cannot find symbol.

  • The end of substring

    substring(0, 3) returns characters 0, 1 and 2; the end is not included. If a position lies beyond the text, the program stops with StringIndexOutOfBoundsException. That also happens with charAt(0) on an empty string.

  • Mixing up char and String

    'a' is a char, "a" is a String. Adding two char values gives a number: 'a' + 'b' is 195. Only when a string is involved are they joined: "" + 'a' + 'b' is "ab".