{"id":"sorting-searching-ready-made","slug":"ready-made-sorting","title":"Java's own sorting methods","text":"Writing selection sort shows what sorting takes, but in real programs you rarely write your own. Java has sorting methods ready, and they use algorithms that are much faster than selection sort on large arrays.\n\n`Arrays.sort(array)` sorts an array, and `Collections.sort(list)` sorts a list. Both classes are in `java.util`, so each needs an import line, like `Scanner`:\n\n```java\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] prices = {250, 120, 310, 90};\n        Arrays.sort(prices);\n        System.out.println(Arrays.toString(prices));\n\n        ArrayList<String> cities = new ArrayList<>();\n        cities.add(\"Oslo\");\n        cities.add(\"Lima\");\n        cities.add(\"Cairo\");\n        Collections.sort(cities);\n        System.out.println(cities);\n    }\n}\n```\n\n```output\n[90, 120, 250, 310]\n[Cairo, Lima, Oslo]\n```\n\n- Numbers sort from the smallest to the largest, and Strings in alphabetical order (with a few surprises, below).\n- Neither method returns anything. They sort the array or the list itself, in place, as `selectionSort` did. The old order is gone, so if the program still needs it, it should keep a copy of the values somewhere else first.\n- `Arrays.sort` works on arrays of numbers and of Strings, such as `int[]`, `double[]` and `String[]`. `Collections.sort` works on lists of them, such as `ArrayList<Integer>` and `ArrayList<String>`.\n\n### The order of Strings\n\nStrings are compared character by character, by each character's code. In those codes, digits come before capital letters, and capital letters come before small ones. So the \"alphabetical\" order holds some surprises:\n\n```java\nArrayList<String> words = new ArrayList<>();\nwords.add(\"banana\");\nwords.add(\"Cherry\");\nwords.add(\"apple\");\nwords.add(\"Apple\");\nCollections.sort(words);\nSystem.out.println(words);\n\nArrayList<String> labels = new ArrayList<>();\nlabels.add(\"9\");\nlabels.add(\"10\");\nlabels.add(\"100\");\nlabels.add(\"25\");\nCollections.sort(labels);\nSystem.out.println(labels);\n```\n\n```output\n[Apple, Cherry, apple, banana]\n[10, 100, 25, 9]\n```\n\n- Every word that starts with a capital letter comes before every word that starts with a small one, so `Cherry` is before `apple`.\n- The labels are Strings, not numbers. `\"10\"` comes before `\"9\"` because its first character, `1`, comes before `9`, just as `\"ba\"` comes before `\"c\"`. When one String is the start of another, the shorter one comes first, so `\"10\"` is before `\"100\"`.\n- Numbers kept as `int` or `Integer` sort by their value. To sort numbers, store them as numbers.\n\n### Your own classes\n\nA list of objects of your own class, such as an `ArrayList<Album>`, can't be sorted this way yet. Java doesn't know whether albums go by title, by year or by something else, so `Collections.sort` on such a list doesn't compile. Part 10 of the course shows how a class tells Java its order, with `Comparable`.\n","task":"A museum counts its visitors every day. Fill in the blanks of `printRange`, which sorts the array of daily counts, prints it, and then prints the fewest and the most visitors in a day. After sorting, where in the array are those two? The check runs:\n\n```java\nint[] visitors = {230, 41, 118, 96, 187};\nprintRange(visitors);\n```\n\nand expects:\n\n```\n[41, 96, 118, 187, 230]\nFewest: 41, most: 230\n```\n","kind":"fill","seed":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] visitors = {230, 41, 118, 96, 187};\n        printRange(visitors);\n    }\n\n    public static void printRange(int[] visitors) {\n        Arrays.[[sort]](visitors);\n        System.out.println(Arrays.toString(visitors));\n        System.out.println(\"Fewest: \" + visitors[[[0]]] + \", most: \" + visitors[[[visitors.length - 1]]]);\n    }\n}\n","solution":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] visitors = {230, 41, 118, 96, 187};\n        printRange(visitors);\n    }\n\n    public static void printRange(int[] visitors) {\n        Arrays.sort(visitors);\n        System.out.println(Arrays.toString(visitors));\n        System.out.println(\"Fewest: \" + visitors[0] + \", most: \" + visitors[visitors.length - 1]);\n    }\n}\n","hints":["`Arrays.sort(visitors)` sorts the array in place, from the smallest count to the largest.","After sorting, the fewest visitors are at the first index, 0, and the most at the last one, `visitors.length - 1`."],"tests":[{"name":"Test 1","stdin":"","call":"int[] visitors = {230, 41, 118, 96, 187};\nprintRange(visitors);\n","expect":"[41, 96, 118, 187, 230]\nFewest: 41, most: 230","hidden":false},{"name":"Test 2","stdin":"","call":"int[] visitors = {300, 12, 45, 12, 290, 1000};\nprintRange(visitors);\nSystem.out.println(visitors[1]);\n","expect":"[12, 12, 45, 290, 300, 1000]\nFewest: 12, most: 1000\n12","hidden":true},{"name":"Test 3","stdin":"","call":"int[] one = {77};\nprintRange(one);\nint[] two = {9, 8};\nprintRange(two);\n","expect":"[77]\nFewest: 77, most: 77\n[8, 9]\nFewest: 8, most: 9","hidden":true}],"require":[],"forbid":[],"more":[{"task":"What does this program print? It sorts the same three numbers twice, once as ints and once as Strings, and then a list of words.\n","kind":"predict","seed":"import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] sizes = {10, 9, 100};\n        Arrays.sort(sizes);\n        System.out.println(Arrays.toString(sizes));\n\n        String[] codes = {\"10\", \"9\", \"100\"};\n        Arrays.sort(codes);\n        System.out.println(Arrays.toString(codes));\n\n        ArrayList<String> fruit = new ArrayList<>();\n        fruit.add(\"pear\");\n        fruit.add(\"Plum\");\n        fruit.add(\"apple\");\n        fruit.add(\"Fig\");\n        Collections.sort(fruit);\n        System.out.println(fruit);\n    }\n}\n","solution":"import java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] sizes = {10, 9, 100};\n        Arrays.sort(sizes);\n        System.out.println(Arrays.toString(sizes));\n\n        String[] codes = {\"10\", \"9\", \"100\"};\n        Arrays.sort(codes);\n        System.out.println(Arrays.toString(codes));\n\n        ArrayList<String> fruit = new ArrayList<>();\n        fruit.add(\"pear\");\n        fruit.add(\"Plum\");\n        fruit.add(\"apple\");\n        fruit.add(\"Fig\");\n        Collections.sort(fruit);\n        System.out.println(fruit);\n    }\n}\n","hints":["The ints sort by their value. The Strings sort character by character, from the first one, and the character `1` comes before `9`. `\"10\"` is the start of `\"100\"`, so it comes first.","Capital letters come before small ones, so the words that start with a capital come first, in alphabetical order among themselves, and then the others."],"tests":[{"name":"Output","stdin":"","expect":"[9, 10, 100]\n[10, 100, 9]\n[Fig, Plum, apple, pear]","hidden":false}],"require":[],"forbid":[],"lines":["[9, 10, 100]","[10, 100, 9]","[Fig, Plum, apple, pear]"]},{"task":"A pizza place logs how many minutes each delivery took. Read the times, one per line, until an empty line, into an `ArrayList<Integer>`. Sort the list with `Collections.sort` and print it. Then print the median: the middle time of the sorted list, with as many times below it as above it. The input always has an odd number of times, so the median is at index `size() / 2`. For the input shown, the program prints:\n\n```\n[19, 22, 28, 34, 41]\nMedian: 28 minutes\n```\n","kind":"code","seed":"import java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<Integer> times = new ArrayList<>();\n\n    }\n}\n","solution":"import java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<Integer> times = new ArrayList<>();\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.isEmpty()) {\n                break;\n            }\n            times.add(Integer.valueOf(line));\n        }\n        Collections.sort(times);\n        System.out.println(times);\n        System.out.println(\"Median: \" + times.get(times.size() / 2) + \" minutes\");\n    }\n}\n","hints":["Read in a `while (true)` loop that stops with `break` at the empty line, and add each time with `times.add(Integer.valueOf(line));`.","After the loop, `Collections.sort(times);` sorts the list in place. With 5 times, `times.size() / 2` is 2, the index of the middle one: `times.get(times.size() / 2)`."],"tests":[{"name":"Test 1","stdin":"34\n22\n41\n28\n19\n\n","expect":"[19, 22, 28, 34, 41]\nMedian: 28 minutes","hidden":false},{"name":"Test 2","stdin":"45\n\n","expect":"[45]\nMedian: 45 minutes","hidden":true},{"name":"Test 3","stdin":"30\n12\n30\n55\n18\n12\n40\n\n","expect":"[12, 12, 18, 30, 30, 40, 55]\nMedian: 30 minutes","hidden":true},{"name":"Test 4","stdin":"9\n60\n25\n\n","expect":"[9, 25, 60]\nMedian: 25 minutes","hidden":true}],"require":[{"pattern":"\\bCollections\\s*\\.\\s*sort\\s*\\(","message":"Sort the list with `Collections.sort`."}],"forbid":[]}]}