diff --git a/Makefile b/Makefile
index 4d81dd08ae6f3e4d6cdbe6457f016e3e42058358..1ba44acdcb2435c1a07de62463e80b736fb7f675 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ pdfs = $(foreach f,$(wildcard $(1)/*.md),$(patsubst %.md,%.pdf,$(f)))
 
 MODEL_PARALLELOGRAM = $(call graphs,$(foreach i,0 1 2 3,parallelogram$(i)))
 INHERITANCE_GRAPHS = $(call graphs,classesTree exceptionsTree)
+IMPLEMENTATION_GRAPHS = $(call graphs,arrayList implementations linkedList newCellArrayList newCellLinkedList)
 
 SLIDES = $(call pdfs,Slides)
 WORKSHEET = $(call pdfs,Worksheet)
@@ -16,6 +17,7 @@ Course.pdf: Course.md $(MODEL_PARALLELOGRAM)
 
 Slides/Class1.pdf: $(MODEL_PARALLELOGRAM) figures/helloworld.tex
 Slides/Class3.pdf: $(INHERITANCE_GRAPHS)
+Slides/Class4.pdf: $(IMPLEMENTATION_GRAPHS)
 
 Slides/%.pdf: Slides/%.md
 	pandoc --toc --slide-level=3 -t beamer $< -o $@
diff --git a/Slides/Class4.md b/Slides/Class4.md
index 0f0f3aeb518e34a1e4c32dbd90fa8c6685654ee1..289d8f1d37c3a4ede4453870481393ba3814c7e7 100644
--- a/Slides/Class4.md
+++ b/Slides/Class4.md
@@ -436,20 +436,205 @@ for(int i = 0; i < newArray.length; i++) {
 
 ## Simple containers
 
+### Implementing interfaces
+
+![A common structure](graphs/implementations.png){height=80px}
+
+One interface, several implementations.
+
 ### Two implementations
 
-### Appending
+#### List
+
+- a set of functionalities
+- a contract to prove a class can act as a list
+
+:::columns
+::::column
+
+#### ArrayList
+
+\vspace{0.5cm}
+
+![](graphs/arrayList.png)
+
+- an array larger than the number of elements
+- an index to remember where it stops
+
+::::
+::::column
+
+#### LinkedList
+
+\vspace{0.5cm}
+
+![](graphs/linkedList.png)
+
+- a "head": the element in the current cell
+- a "queue": the pointer to the rest of the list
+
+::::
+:::
+
+### Getting element at index `i`
+
+:::columns
+::::column
+
+#### ArrayList
+
+\vspace{0.5cm}
+
+- check the bounds: $O(1)$
+- return cell `i`: $O(1)$
+
+$\Rightarrow O(1)$
+
+::::
+::::column
+
+#### LinkedList
+
+\vspace{0.5cm}
+
+does `i == 0 ` ?
+
+- if yes, get the head:
+- otherwise, get the `i-1`\textsuperscript{th} element of the queue
+
+$\Rightarrow O(n)$
+
+::::
+:::
+
+### Prepending
+
+:::columns
+::::column
+
+#### ArrayList
+
+\vspace{0.5cm}
+
+![](graphs/newCellArrayList.png)
+
+- create a new array large enough: $O(n)$
+- write the new element: $O(1)$
+- copy all the other elements after: $O(n)$
+
+$\Rightarrow O(n)$
+
+::::
+::::column
+
+#### LinkedList
+
+\vspace{0.5cm}
+
+![](graphs/newCellLinkedList.png)
+
+- create a new cell with the new element pointing to the existing list: $O(1)$
+
+$\Rightarrow O(1)$
+
+::::
+:::
+
+### Performance comparison
+
+**So which one is best ?**
+
+- if frequent random access is needed: `ArrayList`
+- if frequent modification is needed: `LinkedList`
+
+$\Rightarrow$ No "one-size-fits-all", implementation should match the use
+
+## Associating values to keys
+
+### A common need
+
+- "white pages", phone books…
+- Domain Name System
+- looking up users in a table by their ID
+- retrieving 
+
+```Java
+interface Map<K, V> {
+	…
+	V get(Object k);
+}
+```
+
+### Association list
+
+:::columns
+::::column
+
+```Java
+class Pair<K, V> {
+	…
+}
+```
+
+::::
+::::column
+
+```Java
+class ArrayList<T> {
+	…
+}
+```
+
+::::
+:::
+
+\begin{center}
+$\downarrow$
+\end{center}
 
-### Growing
+```Java
+class PhoneBook<K, V> {
+	private ArrayList<Pair<K, V>> records;
+	PhoneBook (int initialSize) {
+		this.records = new ArrayList<>(initialSize);
+	}
+}
+```
 
-## Associating values to values
+### Retrieving a number from a key
 
-### Pairs list
+```Java
+…
+V get(Object k) {
+	for(Pair<K, V> record: this.records) {
+		if(record.getKey().equals(k)) {
+			return record.getValue();
+		}
+	}
+	return null;
+}
+```
 
-**Need:**
+- must walk the phonebook until found
+- on average, `this.records.size() / 2`
+- $\Rightarrow O(n)$
 
 ### HashMaps
 
+#### A clever implementation
+
+- uses `.hashCode()` on the key: $O(1)$
+- keeps a separate association list for each hash value
+- each list as long as the number of collisions (if `.hashCode` is good, then
+  few): $O(c)$
+- (see birthday problem)
+
+#### Consequences
+
+- fast access
+- fast insertion
+- resizing costs when it gets too full (initial capacity / load factor)
+
 :::columns
 ::::column
 ::::
diff --git a/graphs/arrayList.gv b/graphs/arrayList.gv
new file mode 100644
index 0000000000000000000000000000000000000000..f568935c54ca327656dedba9122b3907ff43b57a
--- /dev/null
+++ b/graphs/arrayList.gv
@@ -0,0 +1,3 @@
+digraph arrayList {
+	Array [ shape="record", label="Cell0|Cell1|Cell2|(empty)|(empty)" ];
+}
diff --git a/graphs/implementations.gv b/graphs/implementations.gv
new file mode 100644
index 0000000000000000000000000000000000000000..9b0bedad0b99778dbc3314e498feb756629d443b
--- /dev/null
+++ b/graphs/implementations.gv
@@ -0,0 +1,7 @@
+digraph implementations {
+	rankdir=BT;
+	Interface [shape="square"];
+	Implementation1 -> Interface;
+	Implementation2 -> Interface;
+	Implementation3 -> Interface;
+}
diff --git a/graphs/linkedList.gv b/graphs/linkedList.gv
new file mode 100644
index 0000000000000000000000000000000000000000..b0fe0bc0afe5996714d0dadb93ffd63af0b06d8c
--- /dev/null
+++ b/graphs/linkedList.gv
@@ -0,0 +1,5 @@
+digraph linkedList {
+	rankdir=LR;
+	Cell0 -> Cell1;
+	Cell1 -> Cell2;
+}
diff --git a/graphs/newCellArrayList.gv b/graphs/newCellArrayList.gv
new file mode 100644
index 0000000000000000000000000000000000000000..2a334b622a9f1549adda38339ad6ab4de0504421
--- /dev/null
+++ b/graphs/newCellArrayList.gv
@@ -0,0 +1,6 @@
+digraph newCellArrayList {
+	rankdir="LR";
+	New [label="New cell", shape="square"];
+	Array [ shape="record", label="{Cell0|Cell1|Cell2|(empty)|(empty)}" ];
+	New -> Array [style="dashed"];
+}
diff --git a/graphs/newCellLinkedList.gv b/graphs/newCellLinkedList.gv
new file mode 100644
index 0000000000000000000000000000000000000000..3b576d389f6b25530b07df0424990fc208fcd193
--- /dev/null
+++ b/graphs/newCellLinkedList.gv
@@ -0,0 +1,7 @@
+digraph linkedList {
+	rankdir=LR;
+	New [label="New cell"];
+	New -> Cell0 [style="dashed"];
+	Cell0 -> Cell1;
+	Cell1 -> Cell2;
+}