Unit 08 · lesson

Use a List When Order and Growth Matter

An array's length is fixed after creation. A List can represent an ordered sequence whose size changes.

var tasks = new ArrayList<String>();
tasks.add("inspect");
tasks.add("test");
tasks.add("document");

IO.println(tasks.size());
IO.println(tasks.get(0));
Concept flow

A mutable List changes structure as operations occur

Order, element type, and mutation behavior are separate properties.

  1. ELEMENT TYPEgeneric type constrains stored references
    create
  2. ORDERED LISTelements occupy a traversable sequence
    mutate
  3. ADD / REMOVEsupported implementations can change contents and size
    changes
  4. NEW STATEmembership and positions may differ
    inspect
  5. EVIDENCEcompare expected and actual contents

The generic type <String> says this list stores String references.

Generics move errors earlier

Without a meaningful element type, a container could become a mystery box.

With:

List<String> names

the compiler can reject an attempt to add an unrelated type.

That is the same theme from Unit 2: constraints can make incorrect states harder to express.

Ordered does not mean sorted

A List preserves an order of elements. That does not mean Java automatically sorts them.

var scores = new ArrayList<Integer>();
scores.add(90);
scores.add(70);
scores.add(85);

Iteration follows list order unless you explicitly perform another operation.

Do not claim "lists are sorted" because the values appeared in the order you added them.

Mutation changes the collection

tasks.remove("test");
tasks.add("review");

Now the list's size and contents have changed.

This is a different model from:

List<String> fixed = List.of("inspect", "test", "document");

The List.of(...) result is not a general mutable ArrayList. Attempts to add/remove are not supported.

The interface type List<String> describes operations conceptually, while the concrete implementation and construction choice affect mutation behavior.

Do you need the index?

for (String task : tasks) {
    IO.println(task);
}

If position matters:

for (int i = 0; i < tasks.size(); i++) {
    IO.println((i + 1) + ". " + tasks.get(i));
}

Use indexed access only when the index has a job.

Build a dynamic queue of evidence labels

Start with an empty ArrayList<String> and add at least five evidence labels in a supplied order.

Then:

  • insert one new label;
  • remove one obsolete label;
  • print the final sequence;
  • search using contains;
  • report the size.

Create expected contents after every mutation before running.

Evidence

Explain why a List fits this problem better than a five-element array. Your reason must mention required operations such as insertion/removal/growth, not simply "List is easier."