Exercise 8 of 10 · Lists
Packing List
What you will make
A travel packing checklist with a banner, one tick-box line for every item you add to the list, and a footer that counts them for you.
The one new idea: ArrayList holds a growable list of values, walked with a for-each loop
Real programs almost never hold one value at a time. They hold a basket of them — orders, messages, students, songs — and walk through the basket doing the same thing to each one. An ArrayList and a for-each loop are how Java does that, and it is a pairing you will reach for constantly.
Go straight to the code ↓A list that can grow
Every variable so far has held exactly one thing at a time. A packing list is not like that — it is one container made of many values, kept in the order you added them, and able to grow after you have already started using it.
Java's built-in array can hold several values too, but its size is fixed the moment it is created: ask it to
grow and javac has nowhere to put the request, because an array simply has no add method. ArrayList is
Java's answer to that — a list that starts however big or small you like and grows one add call at a time.
ArrayList<String> items = new ArrayList<String>();
items.add("Passport");
items.add("Charger");The <String> says what kind of value this particular list holds — text, here — and Java checks that every
time you call add, so trying to add a number to it is caught before the program ever runs, in exactly the
way a mismatched variable type is caught elsewhere.
A loop that hands you values, not numbers
This is the part worth slowing down on, because it looks like the counting loop from the countdown exercise and behaves nothing alike.
for (int n = 0; n < 3; n++) {
System.out.println(n);
}
ArrayList<String> words = new ArrayList<String>();
words.add("yes");
words.add("no");
words.add("maybe");
for (String word : words) {
System.out.println(word);
}The first loop counts. It hands you 0, then 1, then 2 — numbers, every time. The second is a for-each
loop: written for (Type name : collection), it does not count at all. It walks along the list and hands you
each value directly — the text "yes", then "no", then "maybe". You never say how many times to go
round, because the list already knows how long it is, and you never touch an index to reach inside it.
size() says how many
items.size() gives back the number of values currently in the list, worked out fresh every time it is
called — so a list that grows between two calls reports a bigger number on the second one, with nothing else
needing to change.
A worked example
A shed rather than a suitcase, so the answer to this one stays yours to write:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> colours = new ArrayList<String>();
colours.add("red");
colours.add("green");
colours.add("blue");
for (String colour : colours) {
System.out.println("Paint the shed " + colour);
}
System.out.println(colours.size() + " tins on the shelf");
}
}Paint the shed red
Paint the shed green
Paint the shed blue
3 tins on the shelfThree values in the list, three lines of output, then one line that counted them. Add a fourth colour with
one more colours.add(...) line and you get a fourth line and a 4 at the bottom, with nothing else edited.
Your turn
The editor holds a checklist with two items on it. Press Run before changing anything.
The loop is already doing its job: two items in the list, two lines of output. But both lines read
[ ] item, because the line inside the loop prints the word item in plain quotes rather than the value the
variable is holding on that turn. Quotes mean plain text, and plain text is exactly what came out.
Two things to do:
- Rewrite the line inside the loop so it prints the value instead, joining it to the fixed
"[ ] "text with a plus sign, the way the worked example joinscolouron. Keep the[ ]box and the space after it. - Add
items.add("Socks");anditems.add("Towel");on their own lines, straight after the twoaddcalls already there.
The footer needs no attention at all. It already counts the list with items.size(), so it will say 4 by
itself the moment the two new items are in place.
If something goes wrong
The likeliest slip is a missing + and the quotes left around item. You will spot it straight away, because
the output reads [ ] item word for word on every line. Nothing has broken; the line simply needs + item
with no quotes around the variable name.
If the program stops with cannot find symbol: variable length, .length has found its way onto the
ArrayList — that property belongs to arrays. size() is the method that counts an ArrayList.
And if the checklist has only three items where four were meant, a semicolon or an add( may have gone
missing from one of the new lines. Read the two working add calls above it and match their shape exactly.
Write your code
Runs in your browser. Press Run (or Ctrl/Cmd+Enter) and the output is checked for you.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.The runtime is starting in the background. You can type now — it will be ready before you are.
The answer appears here once you have run your code at least once.
Things that often go wrong here
- Trying items.length instead of items.size()
- length is how an array reports how many slots it has, but items here is an ArrayList, not an array, and ArrayList has no field called length at all. javac reports cannot find symbol: variable length, because an ArrayList counts itself with a method instead — size().
- Declaring items as a String[] array so it can be built in one line
- An array's size is fixed the moment it is created, so items.add("Socks"); on a String[] fails to compile with cannot find symbol: method add — arrays have no add method at all. ArrayList exists specifically so a list can grow after it has already been created, which this checklist needs to do.
- Leaving the quotes around item in the println line
- "[ ] item" is plain text, so every row prints the four letters i-t-e-m rather than the value the loop variable is holding on that turn — which is also why both rows come out looking identical no matter how many items are really on the list. There is no error, because a piece of text that happens to say item is a perfectly legal thing to want.
- Typing the new total into the footer by hand
- The footer already works out its own number from items.size(), so it becomes correct the moment the two new items are added — replacing it with a typed number means the line stops telling the truth the next time an item is added or removed.
Want a blank editor instead? Open the Java playground.