{"id":"list-methods-remove","slug":"removing-values","title":"Removing values","text":"`remove` takes a value out of a list. It comes in two kinds:\n\n- `list.remove(index)` removes the value at that index.\n- `list.remove(value)` removes the first copy of that value. If the value isn't in the list, nothing happens.\n\nWhen a value is removed, the list gets one shorter, and every value after it moves down one place: its index goes down by 1.\n\n```java\nArrayList<String> queue = new ArrayList<>();\nqueue.add(\"Ana\");\nqueue.add(\"Ben\");\nqueue.add(\"Cai\");\nqueue.add(\"Dee\");\n\nqueue.remove(0);\nSystem.out.println(queue);\nSystem.out.println(\"First now: \" + queue.get(0));\n\nqueue.remove(\"Dee\");\nSystem.out.println(queue);\nSystem.out.println(\"Size: \" + queue.size());\n```\n\n```output\n[Ben, Cai, Dee]\nFirst now: Ben\n[Ben, Cai]\nSize: 2\n```\n\n### The trap in number lists\n\nIn a list of numbers, `numbers.remove(3)` could mean \"remove index 3\" or \"remove the value 3\". Java always picks the index: an `int` in the parentheses is an index. To remove a value, give `remove` an `Integer`, with `Integer.valueOf`:\n\n```java\nArrayList<Integer> numbers = new ArrayList<>();\nnumbers.add(8);\nnumbers.add(3);\nnumbers.add(5);\nnumbers.add(9);\n\nnumbers.remove(3);\nSystem.out.println(numbers);\n\nnumbers.remove(Integer.valueOf(3));\nSystem.out.println(numbers);\n```\n\n```output\n[8, 3, 5]\n[8, 5]\n```\n\n`numbers.remove(3)` removed the value at index 3, the 9. `Integer.valueOf(3)` is the number 3 as an `Integer`, the type of the list's values, so the second call looks for the value 3. (You've used `Integer.valueOf` on typed text; given an `int`, it works too.) `contains` and `indexOf` have no index kind, so `numbers.contains(3)` always looks for the value.\n\n### Don't remove inside a for-each\n\nA for-each loop doesn't allow its list to grow or shrink while it runs. When it moves on to the next value, it notices that the size changed and stops the program:\n\n```java\nimport java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<Integer> readings = new ArrayList<>();\n        readings.add(12);\n        readings.add(-1);\n        readings.add(15);\n        readings.add(9);\n\n        for (int reading : readings) {\n            if (reading < 0) {\n                readings.remove(Integer.valueOf(reading));\n            }\n        }\n        System.out.println(readings);\n    }\n}\n```\n\n```crash\nException in thread \"main\" java.util.ConcurrentModificationException\n\tat Main.main(Main.java:11)\n```\n\nLine 11 is the for-each line: \"concurrent modification\" means the list was changed while the loop was going through it. (Adding to the list inside the loop does the same. A removal in the second-to-last round goes unnoticed: the loop just ends early and never looks at the last value, which is no better.)\n\nTo remove values while going through a list, use an index loop that goes **backwards**:\n\n```java\nArrayList<Integer> readings = new ArrayList<>();\nreadings.add(12);\nreadings.add(-1);\nreadings.add(-4);\nreadings.add(9);\n\nfor (int i = readings.size() - 1; i >= 0; i--) {\n    if (readings.get(i) < 0) {\n        readings.remove(i);\n    }\n}\nSystem.out.println(readings);\n```\n\n```output\n[12, 9]\n```\n\nGoing from the end, a removal only moves values you've already checked. Going forwards with `i++`, the value after a removed one would move into its place, and the loop would step right past it: here the -4 would be skipped.\n","task":"The program reads prices until `0`, and should remove every price above 50 from the list. It crashes, because it removes inside a for-each loop. Rewrite the removing loop as an index loop that goes backwards. For the input 20, 75, 35, 60, 90 and 10 it prints:\n\n```\nWithin budget: [20, 35, 10]\n```\n","kind":"code","seed":"import java.util.ArrayList;\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> prices = new ArrayList<>();\n        while (true) {\n            int price = Integer.valueOf(scanner.nextLine());\n            if (price == 0) {\n                break;\n            }\n            prices.add(price);\n        }\n\n        for (int price : prices) {\n            if (price > 50) {\n                prices.remove(Integer.valueOf(price));\n            }\n        }\n        System.out.println(\"Within budget: \" + prices);\n    }\n}\n","solution":"import java.util.ArrayList;\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> prices = new ArrayList<>();\n        while (true) {\n            int price = Integer.valueOf(scanner.nextLine());\n            if (price == 0) {\n                break;\n            }\n            prices.add(price);\n        }\n\n        for (int i = prices.size() - 1; i >= 0; i--) {\n            if (prices.get(i) > 50) {\n                prices.remove(i);\n            }\n        }\n        System.out.println(\"Within budget: \" + prices);\n    }\n}\n","hints":["Start at the last index and count down: `for (int i = prices.size() - 1; i >= 0; i--)`.","Inside, check `prices.get(i) > 50` and remove with `prices.remove(i);`. Here `i` is an index, which is just what you want."],"tests":[{"name":"Test 1","stdin":"20\n75\n35\n60\n90\n10\n0\n","expect":"Within budget: [20, 35, 10]","hidden":false},{"name":"Test 2","stdin":"80\n99\n0\n","expect":"Within budget: []","hidden":true},{"name":"Test 3","stdin":"51\n50\n52\n0\n","expect":"Within budget: [50]","hidden":true},{"name":"Test 4","stdin":"12\n5\n0\n","expect":"Within budget: [12, 5]","hidden":true}],"require":[],"forbid":[{"pattern":"for\\s*\\(\\s*\\w+\\s+\\w+\\s*:","message":"Don't remove inside a for-each loop over the same list: use an index loop that goes backwards."}],"more":[{"task":"What does this program print? Check each `remove`: is it given an index or a value?\n","kind":"predict","seed":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<Integer> numbers = new ArrayList<>();\n        numbers.add(4);\n        numbers.add(2);\n        numbers.add(0);\n        numbers.add(1);\n\n        numbers.remove(1);\n        System.out.println(numbers);\n        numbers.remove(Integer.valueOf(1));\n        System.out.println(numbers);\n        numbers.remove(0);\n        System.out.println(numbers);\n    }\n}\n","solution":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<Integer> numbers = new ArrayList<>();\n        numbers.add(4);\n        numbers.add(2);\n        numbers.add(0);\n        numbers.add(1);\n\n        numbers.remove(1);\n        System.out.println(numbers);\n        numbers.remove(Integer.valueOf(1));\n        System.out.println(numbers);\n        numbers.remove(0);\n        System.out.println(numbers);\n    }\n}\n","hints":["`numbers.remove(1)` gets an `int`, so it removes index 1: the 2.","`Integer.valueOf(1)` removes the value 1. Then `remove(0)` is an index again, so it removes the first value, 4."],"tests":[{"name":"Output","stdin":"","expect":"[4, 0, 1]\n[4, 0]\n[0]","hidden":false}],"require":[],"forbid":[],"lines":["[4, 0, 1]","[4, 0]","[0]"]},{"task":"The list `taken` holds the numbers of the taken spots in a parking garage. Read the spot numbers of cars that leave until `0`, and remove each one from the list by its value. Then print what's still taken. For the input `3` and `25` the program prints:\n\n```\nStill taken: [12, 7, 1]\n```\n","kind":"code","seed":"import java.util.ArrayList;\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> taken = new ArrayList<>();\n        taken.add(12);\n        taken.add(3);\n        taken.add(7);\n        taken.add(25);\n        taken.add(1);\n\n    }\n}\n","solution":"import java.util.ArrayList;\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> taken = new ArrayList<>();\n        taken.add(12);\n        taken.add(3);\n        taken.add(7);\n        taken.add(25);\n        taken.add(1);\n\n        while (true) {\n            int spot = Integer.valueOf(scanner.nextLine());\n            if (spot == 0) {\n                break;\n            }\n            taken.remove(Integer.valueOf(spot));\n        }\n        System.out.println(\"Still taken: \" + taken);\n    }\n}\n","hints":["A reading loop that stops at 0, and removes each spot it reads.","`taken.remove(spot)` with an `int` would remove an index. Remove the value: `taken.remove(Integer.valueOf(spot));`"],"tests":[{"name":"Test 1","stdin":"3\n25\n0\n","expect":"Still taken: [12, 7, 1]","hidden":false},{"name":"Test 2","stdin":"1\n0\n","expect":"Still taken: [12, 3, 7, 25]","hidden":true},{"name":"Test 3","stdin":"12\n7\n3\n0\n","expect":"Still taken: [25, 1]","hidden":true},{"name":"Test 4","stdin":"0\n","expect":"Still taken: [12, 3, 7, 25, 1]","hidden":true}],"require":[{"pattern":"\\.remove\\s*\\(","message":"Take each spot out of the list with `remove`."}],"forbid":[]}]}