Day 20 / 25 Java Collections, Generics & Mini-Project 4 0/0 exercises Exercises ↓

AmouAI Hub/Courses/Programming Fundamentals/Day 20

Week 4 · Java: A Second Lens · Day 20

Java Collections, Generics & Mini-Project 4

ArrayList, HashMap and generics — the same structures as Week 2, now with the type system watching.

Study time
4 hours
Reading
Head First Java, Ch. 11
Focus
List · Map · generics

By the end of today you can

  1. Use ArrayList, HashSet and HashMap
  2. Read and write a generic type such as Map<String, List<Integer>>
  3. Say what generics buy over raw collections
  4. Program to the interface (List) rather than the implementation (ArrayList)
  5. Iterate a Map with entrySet()
  6. Recognise the boxing that happens between int and Integer
  7. Deliver Mini-Project 4

Today's videos

Watch each video, then work the matching sections below. Watching alone will not do it.

20A
Collections & Generics (120 min)
ArrayList, HashSet and HashMap &middot; declaring as the interface and creating as the class &middot; reading Map<String, List<Integer>> &middot; life before generics &middot; entrySet() &middot; autoboxing and the Integer cache trap.
20B
Mini-Project 4 Build (120 min)
The Inventory System, built live &middot; abstract base and interface where each belongs &middot; equals/hashCode proven with a HashSet &middot; persistence and malformed input &middot; designing for the JUnit suite that arrives tomorrow.

1The three you will actually use

Week 2's structures, with types attached.

Java's .get() on a Map does not raise

Python'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.

Nested.java
// 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

Boxing.java
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));        // true
Day 17's trap, returning

Generics 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

  1. An abstract InventoryItem with concrete subclasses that differ in behaviour.
  2. An interface — Discountable or similar — implemented by some subclasses only.
  3. An Inventory class holding items in a Map<String, InventoryItem>.
  4. Add, remove, search, and a report sorted by a chosen field.
  5. Correct equals and hashCode on the item classes.
  6. Custom exceptions extending RuntimeException.
  7. Data persists to a file between runs.
  8. 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).
CriterionPoints
Class design — abstract base, honest hierarchy15
Interface used where capability, not identity, is shared10
Collections and generics used correctly15
equals/hashCode correct and paired10
Exceptions raised and handled deliberately10
Persistence, including malformed input10
JUnit suite — 15+ tests20
Naming, structure, Javadoc, formatting10
The written part — 10 of the design marks

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

  1. The abstract base and one subclass. Compile early and often.
  2. The remaining subclasses. Prove the behaviour genuinely differs.
  3. The interface, on the subclasses where it honestly applies.
  4. Inventory with the Map. Get add and search working.
  5. equals/hashCode, then prove a HashSet behaves.
  6. Exceptions, then persistence, then the malformed-file cases.
  7. Tests throughout — not at the end.
You are not learning to program any more

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.

scratch.pypython not loaded
Values for input(), comma separated →
Output appears here. The first run takes a few seconds while Python loads.

Exercise set

Checked automatically the moment you submit. Work top to bottom — each one assumes the last. Your answers are saved in this browser.

All Warm-up Core Challenge Reset day

Day 21 — Java Exceptions, File I/O & JUnit

Checked exceptions are Java's most distinctive design choice.

Continue →