AmouAI Hub/Courses/Programming Fundamentals/Day 20
Java Collections, Generics & Mini-Project 4
ArrayList, HashMap and generics — the same structures as Week 2, now with the type system watching.
By the end of today you can
- Use
ArrayList,HashSetandHashMap - Read and write a generic type such as
Map<String, List<Integer>> - Say what generics buy over raw collections
- Program to the interface (
List) rather than the implementation (ArrayList) - Iterate a
MapwithentrySet() - Recognise the boxing that happens between
intandInteger - Deliver Mini-Project 4
▶Today's videos
Watch each video, then work the matching sections below. Watching alone will not do it.
ArrayList, HashSet and HashMap · declaring as the interface and creating as the class · reading Map<String, List<Integer>> · life before generics · entrySet() · autoboxing and the Integer cache trap.equals/hashCode proven with a HashSet · persistence and malformed input · designing for the JUnit suite that arrives tomorrow.1The three you will actually use
Week 2's structures, with types attached.
.get() on a Map does not raisePython's ages["Nobody"] raises KeyError — loud, locatable. Java's ages.get("Nobody") returns null, quietly, and the failure happens later wherever that null is finally used. Prefer getOrDefault, or check containsKey first.
2Generics
The angle brackets, and what they are for.
List<String> means a list of Strings. Before generics (Java 5), collections held plain Object and you cast on the way out — every retrieval a chance to be wrong.
// read these inside out
Map<String, List<Integer>> scoresByStudent = new HashMap<>();
scoresByStudent.put("Amin", new ArrayList<>());
scoresByStudent.get("Amin").add(88);
// Python's equivalent needs no declaration at all:
// scores_by_student = {}
// scores_by_student["Amin"] = [88]That declaration is long, and it is also documentation the compiler checks. In Python you would have to read the code — or hope for a type hint — to learn the same thing. Neither is free.
Boxing
List<int> bad = new ArrayList<>(); // COMPILE ERROR
List<Integer> good = new ArrayList<>(); // wrapper class
good.add(5); // autoboxed: int -> Integer
int x = good.get(0); // unboxed: Integer -> int
Integer a = 1000, b = 1000;
System.out.println(a == b); // false — two objects!
System.out.println(a.equals(b)); // trueGenerics cannot hold primitives, so int becomes Integer — an object. Which means == compares addresses again. Small values are cached (roughly −128 to 127) so == appears to work, then fails at 1000. Use .equals(), or unbox to int first.
3Mini-Project 4 — Inventory System
Your fourth graded deliverable · 100 points
Rebuild Mini-Project 3's design in Java. Same domain, same behaviour, new rules — and that comparison is the assignment.
Required behaviour
- An abstract
InventoryItemwith concrete subclasses that differ in behaviour. - An interface —
Discountableor similar — implemented by some subclasses only. - An
Inventoryclass holding items in aMap<String, InventoryItem>. - Add, remove, search, and a report sorted by a chosen field.
- Correct
equalsandhashCodeon the item classes. - Custom exceptions extending
RuntimeException. - Data persists to a file between runs.
- A JUnit 5 test suite with at least 15 tests (JUnit arrives properly tomorrow — the brief is published today so you can design for testability from the start).
| Criterion | Points |
|---|---|
| Class design — abstract base, honest hierarchy | 15 |
| Interface used where capability, not identity, is shared | 10 |
| Collections and generics used correctly | 15 |
equals/hashCode correct and paired | 10 |
| Exceptions raised and handled deliberately | 10 |
| Persistence, including malformed input | 10 |
| JUnit suite — 15+ tests | 20 |
| Naming, structure, Javadoc, formatting | 10 |
Submit a one-page note comparing this to Mini-Project 3. Where did Java's compiler catch something Python would have let through? Where did Java make you write five lines for one idea? Which version would you rather maintain in a year, and why? There is no right answer — there is only whether you can argue yours.
Suggested build order
- The abstract base and one subclass. Compile early and often.
- The remaining subclasses. Prove the behaviour genuinely differs.
- The interface, on the subclasses where it honestly applies.
Inventorywith theMap. Get add and search working.equals/hashCode, then prove aHashSetbehaves.- Exceptions, then persistence, then the malformed-file cases.
- Tests throughout — not at the end.
Look at that build order. It is the same one you used for Mini-Projects 1, 2 and 3: smallest working thing first, one new thing at a time, break it on purpose, tidy last. The language changed and the method did not. That method is the thing this course was actually teaching.
>_Python playground
A real Python interpreter running inside your browser. Nothing is installed, nothing is uploaded, nothing can break.
input(), comma separated →
✓Exercise set
Checked automatically the moment you submit. Work top to bottom — each one assumes the last. Your answers are saved in this browser.
Day 21 — Java Exceptions, File I/O & JUnit
Checked exceptions are Java's most distinctive design choice.