Java Arena
Step 5 of 8

equals and lists

The list methods contains, indexOf and remove(value) from module 14 all search the list. To decide whether a value in the list is the one they're looking for, they call equals. With Strings that has always worked, because String has an equals of its own that compares the letters. With objects of your own class, it works as soon as the class has its own equals, like the Seat from the previous step:

Main.java
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Seat> booked = new ArrayList<>();
        booked.add(new Seat("A", 3));
        booked.add(new Seat("B", 7));
        booked.add(new Seat("C", 1));

        System.out.println(booked.contains(new Seat("B", 7)));
        System.out.println(booked.indexOf(new Seat("C", 1)));
        booked.remove(new Seat("A", 3));
        System.out.println(booked);
    }
}
Seat.java
public class Seat {
    private String row;
    private int number;

    public Seat(String row, int number) {
        this.row = row;
        this.number = number;
    }

    public boolean equals(Object compared) {
        if (this == compared) {
            return true;
        }
        if (!(compared instanceof Seat)) {
            return false;
        }
        Seat other = (Seat) compared;
        return this.row.equals(other.row) && this.number == other.number;
    }

    public String toString() {
        return this.row + this.number;
    }
}
Output
true
2
[B7, C1]
  • Each new Seat(...) in the parentheses is a brand-new object, not one of the objects in the list. contains finds it anyway, because it compares with equals, and a seat in the list is equal to it.
  • indexOf gives the index of the first equal seat, and remove(value) removes the first equal seat, as they did with Strings.
  • Printing a list prints each value with its toString, between brackets and separated by commas.

Without the equals method in Seat, all three would miss: contains would print false, indexOf would print -1, and remove wouldn't remove anything. The seat they're given is never the very same object as one in the list, and the equals that every class gets only looks for the same object.

For lists, equals is all it takes. Some of Java's other collections, which come in part 8, also need a second method, hashCode.

Only once in the list

A common use is a list that holds each value only once: before adding, check that no equal value is in it yet.

Seat seat = new Seat(row, number);
if (booked.contains(seat)) {
    System.out.println(seat + " is already taken");
} else {
    booked.add(seat);
    System.out.println("Booked " + seat);
}

Your task

Challenge 1 of 3

At a bakery, the orders waiting to be picked up are in a list, in the order they were placed. Main.java is ready: it reads pick-ups such as Ben bagel (a customer and an item) until an empty line. For each one, it looks for the order's place in line with indexOf, prints it, and takes the order out of the list with remove. But no order is ever found, because Order has no equals of its own. Write equals in Order.java: two orders are equal when they're for the same customer and the same item. For the input shown below, the program prints:

Picked up: bagel for Ben, number 2 in line
No order: muffin for Ada
Picked up: bagel for Di, number 3 in line
Still waiting: [croissant for Ada, muffin for Cy]

Challenge 2

The lost and found keeps the things people have left behind in a list, and Item.java (with equals) is ready. In Main.java, read lines such as red scarf (a color and a thing) until an empty line. For each, make an Item. If an equal item is in the list, remove it from the list and print Returned: and the item; if not, print No and the item and here. At the end, print how many items are left. Let contains and remove do the searching, without a loop over the list. For the input shown below, the program prints:

Returned: red scarf
No green hat here
Returned: red scarf
No red scarf here
Items left: 2

Challenge 3

What does this program print? Tag has no equals of its own.