{"id":"strings-characters","slug":"characters","title":"Characters","text":"A string is a row of characters, and each character has an index, counted from 0, just like the elements of a list or an array. `charAt(index)` gives the character at an index:\n\n| Index | 0 | 1 | 2 | 3 |\n|---|---|---|---|---|\n| `\"Java\"` | J | a | v | a |\n\n```java\nString word = \"Java\";\nchar first = word.charAt(0);\nchar last = word.charAt(word.length() - 1);\nSystem.out.println(first);\nSystem.out.println(last);\n```\n\n```output\nJ\na\n```\n\nThe last index is always `length() - 1`, one less than the length, because counting starts at 0.\n\n### The char type\n\n`charAt` returns a `char`: a type that holds exactly one character. A char is written in **single** quotes, `'a'`, while double quotes make a String, `\"a\"`. Like `int`, `char` is a primitive type, not an object, so chars are compared with `==`:\n\n```java\nString word = \"banana\";\nint count = 0;\nfor (int i = 0; i < word.length(); i++) {\n    char c = word.charAt(i);\n    if (c == 'a') {\n        count++;\n    }\n}\nSystem.out.println(\"The letter a appears \" + count + \" times\");\n```\n\n```output\nThe letter a appears 3 times\n```\n\nThis loop is the way to go through a string: the index runs from 0 as long as it's less than `length()`, and `charAt(i)` gives each character in turn. Other characters work the same way: `' '` is a space and `'!'` an exclamation mark.\n\nA char and a String are different types, even when they hold the same letter, so comparing one with the other doesn't compile:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        String word = \"cat\";\n        if (word.charAt(0) == \"c\") {\n            System.out.println(\"Starts with c\");\n        }\n    }\n}\n```\n\n```javac\nMain.java:4: error: bad operand types for binary operator '=='\n        if (word.charAt(0) == \"c\") {\n                           ^\n  first type:  char\n  second type: String\n1 error\n```\n\nOne more surprise: a char is stored as a number, its character code, so `+` between two chars adds their codes. With a String first, `+` joins as usual:\n\n```java\nString word = \"ok\";\nSystem.out.println(word.charAt(0) + word.charAt(1));\nSystem.out.println(\"\" + word.charAt(0) + word.charAt(1));\n```\n\n```output\n218\nok\n```\n\n### Past the end\n\nThe indexes of `\"cat\"` are 0, 1 and 2. Asking for index 3 crashes the program with a `StringIndexOutOfBoundsException`. The usual cause is a loop that uses `<=` where it should use `<`:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        String word = \"cat\";\n        for (int i = 0; i <= word.length(); i++) {\n            System.out.println(word.charAt(i));\n        }\n    }\n}\n```\n\n```output\nc\na\nt\n```\n\n```crash\nException in thread \"main\" java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3\n\tat Main.main(Main.java:5)\n```\n\nThe message says which index was asked for and how long the string is, and the `at` line points to line 5, the `charAt` call. The loop condition should be `i < word.length()`.\n","task":"Fill in the blanks, so the program counts the question marks in a line. For the input `Who? What? Why?` it prints:\n\n```\nQuestions: 3\n```\n","kind":"fill","seed":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        String text = scanner.nextLine();\n        int count = 0;\n        for (int i = 0; i < text.[[length]](); i++) {\n            if (text.[[charAt]](i) == '?') {\n                count++;\n            }\n        }\n        System.out.println(\"Questions: \" + count);\n    }\n}\n","solution":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        String text = scanner.nextLine();\n        int count = 0;\n        for (int i = 0; i < text.length(); i++) {\n            if (text.charAt(i) == '?') {\n                count++;\n            }\n        }\n        System.out.println(\"Questions: \" + count);\n    }\n}\n","hints":["The loop runs as long as `i` is less than the number of characters in `text`.","The character at index `i` is `text.charAt(i)`."],"tests":[{"name":"Test 1","stdin":"Who? What? Why?\n","expect":"Questions: 3","hidden":false},{"name":"Test 2","stdin":"No questions here.\n","expect":"Questions: 0","hidden":true},{"name":"Test 3","stdin":"???\n","expect":"Questions: 3","hidden":true}],"require":[],"forbid":[],"more":[{"task":"Write a method `countVowels(String text)` that returns how many vowels (a, e, i, o and u, small or capital) the text has. The check runs `System.out.println(countVowels(\"Education\"));` and expects:\n\n```\n5\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(countVowels(\"Education\"));\n    }\n\n    // Write the countVowels method here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(countVowels(\"Education\"));\n    }\n\n    public static int countVowels(String text) {\n        String lower = text.toLowerCase();\n        int count = 0;\n        for (int i = 0; i < lower.length(); i++) {\n            char c = lower.charAt(i);\n            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n","hints":["Make the text small first, `String lower = text.toLowerCase();`, so there are only five vowels to look for.","In the loop, `char c = lower.charAt(i);` and then `if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')`."],"tests":[{"name":"System.out.println(countVowels(\"Education\"));","stdin":"","call":"System.out.println(countVowels(\"Education\"));\n","expect":"5","hidden":false},{"name":"System.out.println(countVowels(\"rhythm\"));","stdin":"","call":"System.out.println(countVowels(\"rhythm\"));\n","expect":"0","hidden":true},{"name":"System.out.println(countVowels(\"AEIOU aeiou\"));","stdin":"","call":"System.out.println(countVowels(\"AEIOU aeiou\"));\n","expect":"10","hidden":true},{"name":"System.out.println(countVowels(\"\"));","stdin":"","call":"System.out.println(countVowels(\"\"));\n","expect":"0","hidden":true},{"name":"System.out.println(countVowels(\"Programming in Java\"));","stdin":"","call":"System.out.println(countVowels(\"Programming in Java\"));\n","expect":"6","hidden":true}],"require":[{"pattern":"\\.charAt\\s*\\(","message":"Look at the characters one at a time with `charAt`."}],"forbid":[]},{"task":"What does this program print? The loop runs backwards.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        String word = \"drawer\";\n        String result = \"\";\n        for (int i = word.length() - 1; i >= 0; i--) {\n            result += word.charAt(i);\n        }\n        System.out.println(result);\n        System.out.println(word.charAt(1) + \"\" + word.charAt(4));\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        String word = \"drawer\";\n        String result = \"\";\n        for (int i = word.length() - 1; i >= 0; i--) {\n            result += word.charAt(i);\n        }\n        System.out.println(result);\n        System.out.println(word.charAt(1) + \"\" + word.charAt(4));\n    }\n}\n","hints":["The loop starts at the last index, 5, and goes down to 0, adding one character in each round.","`drawer` backwards is `reward`. On the last line, the `\"\"` in the middle makes `+` join the two chars instead of adding their codes."],"tests":[{"name":"Output","stdin":"","expect":"reward\nre","hidden":false}],"require":[],"forbid":[],"lines":["reward","re"]}]}