diff --git a/src/tp4/ex2/Adressage.java b/src/tp4/ex2/Adressage.java
index 7fa78a92146fc67b871e753561e66c3b3e3f89c8..7c8bb550d3361e3ccb637ae6b8d32756d2476863 100644
--- a/src/tp4/ex2/Adressage.java
+++ b/src/tp4/ex2/Adressage.java
@@ -3,23 +3,24 @@ package tp4.ex2;
 import java.util.Arrays;
 import java.util.stream.Collectors;
 
-public class Adressage implements HashTable {
+public class Adressage<K, V> implements HashTable<K, V> {
 	private static final int NOT_FOUND = -1;
 	public static final int DEFAULT_SIZE = 2048;
 
-	private HashCouple[] table;
+	private HashCouple<K, V>[] table;
 	private int currentSize = 0;
 	
 	public Adressage() {
 		this(DEFAULT_SIZE);
 	}
 	
+	@SuppressWarnings("unchecked")
 	public Adressage(int capacity) {
 		table = new HashCouple[capacity];
 	}
 
 	@Override
-	public Integer get(String key) {
+	public V get(K key) {
 		final int idx = find(key);
 		
 		if (idx != NOT_FOUND) {
@@ -30,30 +31,30 @@ public class Adressage implements HashTable {
 	}
 
 	@Override
-	public Integer put(String key, Integer value) {
+	public V put(K key, V value) {
 		final int hash = getHash(key);
 		
 		for (int idx = hash, cpt = 0; cpt < table.length; idx = next(idx), ++cpt) {
 			if (table[idx] == null) {
-				table[idx] = new HashCouple(key, value);
+				table[idx] = new HashCouple<K, V>(key, value);
 				++currentSize;
 				return null;
 			} else if (table[idx].getKey().equals(key)) {
-				Integer oldVal = table[idx].getValue();
+				V oldVal = table[idx].getValue();
 				table[idx].setValue(value);
 				return oldVal;
 			}
 		}
 		
-		return null;
+		throw new IllegalStateException();
 	}
 
 	@Override
-	public Integer remove(String key) {
+	public V remove(K key) {
 		final int idx = find(key);
 		
 		if (idx != NOT_FOUND) {
-			final HashCouple c = table[idx];
+			final HashCouple<K, V> c = table[idx];
 
 			table[idx] = null;
 			--currentSize;
@@ -64,14 +65,14 @@ public class Adressage implements HashTable {
 	}
 
 	@Override
-	public boolean contains(String key) {
+	public boolean contains(K key) {
 		return find(key) != NOT_FOUND;
 	}
 
 	@Override
 	public void clear() {
 		currentSize = 0;
-		Arrays.fill(table, (HashCouple)null);
+		Arrays.fill(table, (HashCouple<K, V>)null);
 	}
 
 	@Override
@@ -79,12 +80,12 @@ public class Adressage implements HashTable {
 		return currentSize;
 	}
 	
-	private int find(String key) {
+	private int find(K key) {
 		final int hash = getHash(key);
 		
 		int idx = hash, loop = 0;
 		
-		HashCouple c = null;
+		HashCouple<K, V> c = null;
 		
 		// TODO: Optimiser en transformant en while si possible
 		for (;loop < table.length; ++loop) {
@@ -110,7 +111,7 @@ public class Adressage implements HashTable {
 		return result;
 	}
 	
-	private int getHash(String key) {	
+	private int getHash(K key) {	
 		return Math.abs(key.hashCode()) % table.length;
 	}
 	
diff --git a/src/tp4/ex2/Chainage.java b/src/tp4/ex2/Chainage.java
index 84ed3988f7b2d1c55943a35325d31fb9b18a76bc..fdd10d08de5dbbded68ad937b6510e75a3b00ae6 100644
--- a/src/tp4/ex2/Chainage.java
+++ b/src/tp4/ex2/Chainage.java
@@ -6,9 +6,9 @@ import java.util.LinkedList;
 import java.util.stream.Collectors;
 
 @SuppressWarnings("unchecked")
-public class Chainage implements HashTable {
+public class Chainage<K, V> implements HashTable<K, V> {
 	public static final int DEFAULT_SIZE = 16;
-	private LinkedList<HashCouple>[] table;
+	private LinkedList<HashCouple<K, V>>[] table;
 	private int currentSize = 0;
 	
 	public Chainage() {
@@ -19,38 +19,38 @@ public class Chainage implements HashTable {
 		table = new LinkedList[capacity];
 
 		for (int i = 0; i < capacity; ++i) {
-			table[i] = new LinkedList<HashCouple>();
+			table[i] = new LinkedList<HashCouple<K, V>>();
 		}
 	}
 
 	@Override
-	public Integer put(String key, Integer value) {
-		HashCouple c = find(key);
+	public V put(K key, V value) {
+		HashCouple<K, V> c = find(key);
 		
 		if (c == null) {
 			final int hash = getHash(key);
-			c = new HashCouple(key, value);
+			c = new HashCouple<K, V>(key, value);
 			table[hash].add(c);
 			++currentSize;
 			return null;
 		} else {
-			int old = c.getValue();
+			V old = c.getValue();
 			c.setValue(value);
 			return old;
 		}
 	}
 
 	@Override
-	public Integer get(String key) {
-		final HashCouple c = find(key);
+	public V get(K key) {
+		final HashCouple<K, V> c = find(key);
 		return c != null ? c.getValue() : null;
 	}
 
 	@Override
-	public Integer remove(String key) {
+	public V remove(K key) {
 		final int hash = getHash(key);
 		
-		final HashCouple c = find(key);
+		final HashCouple<K, V> c = find(key);
 		
 		if (c != null) {
 			table[hash].remove(c);
@@ -62,12 +62,12 @@ public class Chainage implements HashTable {
 	}
 
 	@Override
-	public boolean contains(String key) {
+	public boolean contains(K key) {
 		return find(key) != null;
 	}
 
 	public void clear() {
-		for (LinkedList<HashCouple> list : table) {
+		for (LinkedList<HashCouple<K, V>> list : table) {
 			list.clear();
 		}
 		
@@ -79,18 +79,18 @@ public class Chainage implements HashTable {
 		return currentSize;
 	}
 
-	private HashCouple find(String key) {
+	private HashCouple<K, V> find(K key) {
 		final int hash = getHash(key);
 		
-		Iterator<HashCouple> it = table[hash].iterator();
+		Iterator<HashCouple<K, V>> it = table[hash].iterator();
 		
-		HashCouple c = null;
+		HashCouple<K, V> c = null;
 		while (it.hasNext() && !(c = it.next()).getKey().equals(key));
 		
 		return (c != null && c.getKey().equals(key)) ? c : null;
 	}
 	
-	private int getHash(String key) {
+	private int getHash(K key) {
 		return Math.abs(key.hashCode()) % table.length;
 	}
 	
diff --git a/src/tp4/ex2/HashCouple.java b/src/tp4/ex2/HashCouple.java
index b737cae0f02272090225c28dadf2dcff0253823d..083f60e1795decedd61e8d25a56123513332b026 100644
--- a/src/tp4/ex2/HashCouple.java
+++ b/src/tp4/ex2/HashCouple.java
@@ -2,10 +2,10 @@ package tp4.ex2;
 
 import java.util.AbstractMap;
 
-public class HashCouple extends AbstractMap.SimpleEntry<String, Integer> {
+public class HashCouple<K, V> extends AbstractMap.SimpleEntry<K, V> {
 	private static final long serialVersionUID = 1L;
 
-	public HashCouple(String key, Integer value) {
+	public HashCouple(K key, V value) {
 		super(key, value);
 	}
 	
@@ -14,6 +14,7 @@ public class HashCouple extends AbstractMap.SimpleEntry<String, Integer> {
 		return getKey().hashCode();
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj) {
@@ -27,7 +28,7 @@ public class HashCouple extends AbstractMap.SimpleEntry<String, Integer> {
 			return false;
 		}
 		
-		HashCouple other = (HashCouple)obj;
+		HashCouple<K, V> other = (HashCouple<K, V>)obj;
 		
 		if (!getKey().equals(other.getKey())) {
 			return false;
diff --git a/src/tp4/ex2/HashTable.java b/src/tp4/ex2/HashTable.java
index 2c70c8234966f7ab06a5bc4d6f81c10e3dc1c55f..bb78f6512f758ab2c2433c4a02ffaf737ec45ef5 100644
--- a/src/tp4/ex2/HashTable.java
+++ b/src/tp4/ex2/HashTable.java
@@ -1,10 +1,10 @@
 package tp4.ex2;
 
-public interface HashTable {
-	public Integer get(String key);
-	public Integer put(String key, Integer value);
-	public Integer remove(String key);
-	public boolean contains(String key);
+public interface HashTable<K, V> {
+	public V get(K key);
+	public V put(K key, V value);
+	public V remove(K key);
+	public boolean contains(K key);
 	public void clear();
 	public int size();
 }
diff --git a/test/tp4/ex2/HashTableTest.java b/test/tp4/ex2/HashTableTest.java
index 2b6cd57832924f4598b65f444bac109747579c90..cba3b1575a493bc3df17638383b6cc4c0701a3c6 100644
--- a/test/tp4/ex2/HashTableTest.java
+++ b/test/tp4/ex2/HashTableTest.java
@@ -14,14 +14,14 @@ public class HashTableTest {
 	protected static Stream<Arguments> arguments() {
 		return Stream
 		.of(
-			Arguments.of(new Chainage()),
-			Arguments.of(new Adressage())
+			Arguments.of(new Chainage<String, Integer>()),
+			Arguments.of(new Adressage<String, Integer>())
 		);
 	}
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testToString(HashTable table) {
+	protected void testToString(HashTable<String, Integer> table) {
 		table.put("def", 2);
 		table.put("ghi", 3);
 		table.put("abc", 1);
@@ -31,7 +31,7 @@ public class HashTableTest {
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testPut(HashTable table) {
+	protected void testPut(HashTable<String, Integer> table) {
 		assertEquals(null, table.put("abc", 1));
 		assertEquals(1, table.put("abc", 2));
 		assertEquals(null, table.put("def", 8));
@@ -41,7 +41,7 @@ public class HashTableTest {
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testRemove(HashTable table) {
+	protected void testRemove(HashTable<String, Integer> table) {
 		table.put("abc", 123);
 		table.put("def", 456);
 		table.put("ghi", 789);
@@ -53,7 +53,7 @@ public class HashTableTest {
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testGet(HashTable table) {
+	protected void testGet(HashTable<String, Integer> table) {
 		table.put("abc", 123);
 		table.put("def", 456);
 		table.put("ghi", 789);
@@ -67,7 +67,7 @@ public class HashTableTest {
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testSize(HashTable table) {
+	protected void testSize(HashTable<String, Integer> table) {
 		assertEquals(0, table.size());
 
 		table.put("abc", 100);
@@ -88,7 +88,7 @@ public class HashTableTest {
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testClear(HashTable table) {
+	protected void testClear(HashTable<String, Integer> table) {
 		assertEquals(0, table.size());
 
 		table.put("a", 1);
@@ -105,7 +105,7 @@ public class HashTableTest {
 
 	@ParameterizedTest
 	@MethodSource("arguments")
-	protected void testContains(HashTable table) {
+	protected void testContains(HashTable<String, Integer> table) {
 		assertFalse(table.contains("abc"));
 
 		table.put("abc", 100);