Java Project: Reservation Ledger
Build a small reservation ledger that rejects duplicate references and prevents a session from accepting more people than it has seats. Start with an in-memory model before adding files or a user interface.
Your brief
Write the rules before the methods: references are unique, requested seats are positive, and accepted totals never exceed capacity. A rejected request must leave the ledger unchanged. Keep the ledger responsible for these rules instead of asking every caller to remember them. This first version deliberately handles one session on one thread. It does not provide persistence, authentication, payment processing or concurrent booking safety. Those are separate design decisions, not properties obtained by putting values in a map.
Run it locally
Use a local JDK 21 or newer. Save the complete example as Main.java in a separate lab folder, then compile and run it with the commands below. Java examples do not run in Bhylu’s browser playground. The -ea option enables assertion checks used by some lessons.
javac --release 21 -encoding UTF-8 -d out Main.java
java -ea -cp out MainWorked solution
Show the worked solution
import java.util.HashMap;
import java.util.Map;
public class Main {
static final class Ledger {
private final int capacity;
private final Map<String, Integer> bookings = new HashMap<>();
Ledger(int capacity) {
if (capacity < 0) throw new IllegalArgumentException("Negative capacity");
this.capacity = capacity;
}
boolean reserve(String reference, int seats) {
if (reference == null || reference.isBlank() || seats <= 0)
throw new IllegalArgumentException("Invalid reservation");
if (bookings.containsKey(reference) || seats > remaining()) return false;
bookings.put(reference, seats);
return true;
}
int remaining() {
return capacity - bookings.values().stream().mapToInt(Integer::intValue).sum();
}
}
public static void main(String[] args) {
Ledger ledger = new Ledger(6);
System.out.println(ledger.reserve("R1", 4));
System.out.println(ledger.reserve("R1", 1));
System.out.println(ledger.reserve("R2", 3));
System.out.println(ledger.reserve("R3", 2));
if (ledger.remaining() != 0) throw new AssertionError("Seat invariant");
System.out.println("Remaining: " + ledger.remaining());
}
}
Expected output
true
false
false
true
Remaining: 0The first request reserves four seats. Reusing its reference fails without replacing those four seats. A request for three fails because only two remain. The last request fits exactly. The explicit invariant check throws even when JVM assertions are disabled. Test invalid input separately: it is a programming/input contract error rather than a normal capacity rejection.
Extend and test
Add cancel(reference), returning the cancelled seat count or zero. Check that cancelling twice releases seats only once. Then add tests for zero capacity, blank references and an exact-fit reservation.
Check the official Java documentation for detailed contracts and supported options.