{"id":"strings-reading-printing","slug":"strings-again","title":"Strings again","text":"Strings have been with you since module 2: `nextLine()` reads one, `+` joins them, and `println` prints them. You've compared them with `equals` (module 6) and built them up in a loop with `+=` (module 11). This module is about what else you can do with text: look at its characters, cut out pieces, and split a line into parts. That's how a program makes sense of input such as `Aino,42`.\n\n### Methods of a String\n\nA String has methods of its own. You call them with a dot after the string, the same way you call `nextLine()` on a scanner. `length()` tells how many characters the string has:\n\n```java\nScanner scanner = new Scanner(System.in);\nSystem.out.println(\"Name of your pet?\");\nString pet = scanner.nextLine();\nSystem.out.println(pet + \" has \" + pet.length() + \" characters\");\n```\n\n```input\nMr Biscuit\n```\n\n```output\nName of your pet?\nMr Biscuit has 10 characters\n```\n\nEvery character counts, the space included. The empty string `\"\"`, which is what `nextLine()` gives when the user presses Enter without typing anything, has the length 0. `isEmpty()` is `true` for it, and `false` for any other string.\n\n### Strings can't be changed\n\n`toUpperCase()`, `toLowerCase()` and `trim()` look as if they change a string, but they don't: each one gives back a **new** string. `trim()` removes the spaces at the start and at the end, not the ones in the middle. The brackets show where the spaces are:\n\n```java\nString title = \"  Tea Time \";\nSystem.out.println(\"[\" + title.toUpperCase() + \"]\");\nSystem.out.println(\"[\" + title.toLowerCase() + \"]\");\nSystem.out.println(\"[\" + title.trim() + \"]\");\nSystem.out.println(\"[\" + title + \"]\");\n```\n\n```output\n[  TEA TIME ]\n[  tea time ]\n[Tea Time]\n[  Tea Time ]\n```\n\nThe last line shows that `title` is still what it was. No String method ever changes the string it's called on: Strings are **immutable**. To keep a result, store it, often in the same variable: `title = title.trim();`. A line like `title.trim();` on its own does nothing useful, because the new string is thrown away, just like the value of a method call that isn't used (module 11).\n\nSince each of these methods returns a string, you can call another method on the result straight away. `title.trim().toUpperCase()` trims first and then makes capitals of the trimmed text: `TEA TIME`.\n","task":"Fill in the blanks. The program reads a word and prints it in capitals, followed by its length in parentheses. For the input `java` it prints:\n\n```\nJAVA (4)\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 word = scanner.nextLine();\n        System.out.println(word.[[toUpperCase]]() + \" (\" + word.[[length]]() + \")\");\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 word = scanner.nextLine();\n        System.out.println(word.toUpperCase() + \" (\" + word.length() + \")\");\n    }\n}\n","hints":["The method that gives the text in capitals is `toUpperCase`.","The number of characters comes from `length()`."],"tests":[{"name":"Test 1","stdin":"java\n","expect":"JAVA (4)","hidden":false},{"name":"Test 2","stdin":"Hello world\n","expect":"HELLO WORLD (11)","hidden":true},{"name":"Test 3","stdin":"x\n","expect":"X (1)","hidden":true}],"require":[],"forbid":[],"more":[{"task":"People type email addresses in all sorts of ways, with capitals and stray spaces. Write a method `cleanEmail(String email)` that returns the address without the spaces at the start and the end, and in small letters. The check runs `System.out.println(\"[\" + cleanEmail(\"  Ada@Example.COM \") + \"]\");` and expects:\n\n```\n[ada@example.com]\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(\"[\" + cleanEmail(\"  Ada@Example.COM \") + \"]\");\n    }\n\n    // Write the cleanEmail method here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(\"[\" + cleanEmail(\"  Ada@Example.COM \") + \"]\");\n    }\n\n    public static String cleanEmail(String email) {\n        return email.trim().toLowerCase();\n    }\n}\n","hints":["The method returns a String: `public static String cleanEmail(String email) {`.","`trim()` and `toLowerCase()` each return a new string, so they can be chained: `return email.trim().toLowerCase();`"],"tests":[{"name":"System.out.println(\"[\" + cleanEmail(\"  Ada@Example.COM \") + \"]\");","stdin":"","call":"System.out.println(\"[\" + cleanEmail(\"  Ada@Example.COM \") + \"]\");\n","expect":"[ada@example.com]","hidden":false},{"name":"System.out.println(\"[\" + cleanEmail(\"grace@example.org\") + \"]\");","stdin":"","call":"System.out.println(\"[\" + cleanEmail(\"grace@example.org\") + \"]\");\n","expect":"[grace@example.org]","hidden":true},{"name":"System.out.println(\"[\" + cleanEmail(\"   LINUS@EXAMPLE.NET\") + \"]\");","stdin":"","call":"System.out.println(\"[\" + cleanEmail(\"   LINUS@EXAMPLE.NET\") + \"]\");\n","expect":"[linus@example.net]","hidden":true},{"name":"System.out.println(\"[\" + cleanEmail(\" Mo@Example.com  \") + \"]\");","stdin":"","call":"System.out.println(\"[\" + cleanEmail(\" Mo@Example.com  \") + \"]\");\n","expect":"[mo@example.com]","hidden":true}],"require":[{"pattern":"\\.trim\\s*\\(","message":"Remove the spaces with `trim()`."},{"pattern":"\\.toLowerCase\\s*\\(","message":"Make the letters small with `toLowerCase()`."}],"forbid":[]},{"task":"What does this program print? Watch which results are kept.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        String city = \"Lima\";\n        city.toUpperCase();\n        System.out.println(city);\n        city = city.toUpperCase();\n        System.out.println(city);\n        System.out.println(city.length() + city.toLowerCase());\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        String city = \"Lima\";\n        city.toUpperCase();\n        System.out.println(city);\n        city = city.toUpperCase();\n        System.out.println(city);\n        System.out.println(city.length() + city.toLowerCase());\n    }\n}\n","hints":["`city.toUpperCase();` on a line of its own makes a new string and throws it away, so `city` is still `Lima`.","After `city = city.toUpperCase();` the variable holds `LIMA`. On the last line, the number 4 is joined to the text `lima`."],"tests":[{"name":"Output","stdin":"","expect":"Lima\nLIMA\n4lima","hidden":false}],"require":[],"forbid":[],"lines":["Lima","LIMA","4lima"]}]}