Home › Learn › Java › Strings and text

Characters

Lesson 22 of 40. Walk a string one char at a time.

A char is one character, written in single quotes: 'a'. text.charAt(i) reads one, text.length() bounds a loop over them, and text.toCharArray() gives a char[] for a for-each loop. The Character class answers questions: Character.isDigit(c), isLetter(c), isUpperCase(c), and converts: Character.toUpperCase(c). A digit character becomes its number with c - '0', because chars are numbers underneath ('7' - '0' is 7).

Building a string char by char with += works for short strings; the next lesson has the tool for long ones.

Books are identified by ISBN, and an ISBN-10 carries its own check: the digits are weighted 10 down to 1, summed, and the total must divide by 11 (the last position may be X, which counts as 10). The class Isbn in this lesson checks that, and the library project refuses books that fail it.

int digits = 0;
for (char c : text.toCharArray()) {
    if (Character.isDigit(c)) {
        digits++;
    }
}

Your task

In Main, write static int countVowels(String text) counting a e i o u in either case, and static boolean isPalindrome(String text) returning whether the text reads the same backwards, ignoring case and anything that is not a letter or digit ("A man, a plan, a canal: Panama" is one).

In the class Isbn, write static boolean isValid(String isbn): the text must be exactly 10 characters, the first nine digits, the last a digit or X; then the sum of weight * value with weights 10, 9, ..., 1 (and X worth 10) must be a multiple of 11. "0306406152" is valid; "0306406153" is not.

Part of the final project. Isbn checks the check digit of an ISBN-10 before a book is accepted into the catalog. It is saved in this browser and loaded into Project: the library when you get there.

Hint 1

countVowels: for each char c of text.toLowerCase(), count when "aeiou".indexOf(c) >= 0. isPalindrome: build a cleaned string of Character.toLowerCase(c) for letters and digits (Character.isLetterOrDigit), then compare it with its reverse.

Hint 2

isValid: if (isbn.length() != 10) return false; loop i from 0 to 9: char c = isbn.charAt(i); value is c - '0' for a digit, 10 for an X in the last position, otherwise return false; sum += (10 - i) * value; finally return sum % 11 == 0.

Show the solution
public class Main {
    static int countVowels(String text) {
        int count = 0;
        for (char c : text.toLowerCase().toCharArray()) {
            if ("aeiou".indexOf(c) >= 0) {
                count++;
            }
        }
        return count;
    }

    static boolean isPalindrome(String text) {
        String cleaned = "";
        for (char c : text.toCharArray()) {
            if (Character.isLetterOrDigit(c)) {
                cleaned += Character.toLowerCase(c);
            }
        }
        for (int i = 0; i < cleaned.length() / 2; i++) {
            if (cleaned.charAt(i) != cleaned.charAt(cleaned.length() - 1 - i)) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(countVowels("Programming") + " " + isPalindrome("racecar") + " " + Isbn.isValid("0306406152"));
    }
}

class Isbn {
    static boolean isValid(String isbn) {
        if (isbn.length() != 10) {
            return false;
        }
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            char c = isbn.charAt(i);
            int value;
            if (Character.isDigit(c)) {
                value = c - '0';
            } else if (c == 'X' && i == 9) {
                value = 10;
            } else {
                return false;
            }
            sum += (10 - i) * value;
        }
        return sum % 11 == 0;
    }
}

    Compiles with OpenJDK javac and TeaVM, both compiled to WebAssembly (7 MB download the first time, then cached), and runs in this tab; nothing is sent anywhere.