JAVA HashMap 2D, cant get the right approach to make a 2D HashMap, i mean a HashMap into another HashMap

hashmap, java, nested

Solution

You can use this class:

public class BiHashMap<K1, K2, V> {

private final Map<K1, Map<K2, V>> mMap;

public BiHashMap() {
    mMap = new HashMap<K1, Map<K2, V>>();
}

/**
 * Associates the specified value with the specified keys in this map (optional operation). If the map previously
 * contained a mapping for the key, the old value is replaced by the specified value.
 * 
 * @param key1
 *            the first key
 * @param key2
 *            the second key
 * @param value
 *            the value to be set
 * @return the value previously associated with (key1,key2), or <code>null</code> if none
 * @see Map#put(Object, Object)
 */
public V put(K1 key1, K2 key2, V value) {
    Map<K2, V> map;
    if (mMap.containsKey(key1)) {
        map = mMap.get(key1);
    } else {
        map = new HashMap<K2, V>();
        mMap.put(key1, map);
    }

    return map.put(key2, value);
}

/**
 * Returns the value to which the specified key is mapped, or <code>null</code> if this map contains no mapping for
 * the key.
 * 
 * @param key1
 *            the first key whose associated value is to be returned
 * @param key2
 *            the second key whose associated value is to be returned
 * @return the value to which the specified key is mapped, or <code>null</code> if this map contains no mapping for
 *         the key
 * @see Map#get(Object)
 */
public V get(K1 key1, K2 key2) {
    if (mMap.containsKey(key1)) {
        return mMap.get(key1).get(key2);
    } else {
        return null;
    }
}

/**
 * Returns <code>true</code> if this map contains a mapping for the specified key
 * 
 * @param key1
 *            the first key whose presence in this map is to be tested
 * @param key2
 *            the second key whose presence in this map is to be tested
 * @return Returns true if this map contains a mapping for the specified key
 * @see Map#containsKey(Object)
 */
public boolean containsKeys(K1 key1, K2 key2) {
    return mMap.containsKey(key1) && mMap.get(key1).containsKey(key2);
}

public void clear() {
    mMap.clear();
}

}

And then create use it like this:

BiHashMap<String,String,String> bigBoard = new BiHashMap<String,String,String>();

However for performance you may want to store the different grades in an array (assuming that you have a fix set of courses)

Problem

I want to make a board of Students' names and Subjects and each student has a grade in each subject (or not.. he can leave the exam and doesnt write it, and then his case will be empty). I want to use just HashMaps. I mean, it will be something like that: ``` HashMap<String,HashMap<String,String>> bigBoard = new HashMap<String,HashMap<String,String>>(); ``` but I think, I dont have the right idea, because for each subject, there will be many grades (values) so that won't be possible. Do I have to make a map for each student? with his subject? but then the table on output won't be arranged. Do you have a proposition? I would like a table that look like something like that for example. ``` Column-Key → Rowkey↓ Mathematics Physics Finance Daniel Dolter 1.3 3.7 Micky Mouse 5 Minnie Mouse 1.7 n/a Dagobert Duck 4.0 1.0 ``` (I would use all the keys/values as Strings, it will be more simple like that.) After the implementation of our class (for example class-name is String2D), we should use it like that. ``` public static void main(String[] args) { String2D map2D = new String2D(); map2D.put("Daniel Doster", "Practical Mathematics", "1.3"); map2D.put("Daniel Doster", "IT Systeme", "3.7"); map2D.put("Micky Mouse", "Finance", "5"); map2D.put("Minnie Mouse", "IT Systeme", "1.7"); map2D.put("Minnie Mouse", "Finance", "n/a"); map2D.put("Dagobert Duck", "Practical Mathematics", "4.0"); map2D.put("Dagobert Duck", "Finance", "1.0"); System.out.println(map2D); } ``` No "HashMap" will be seen.. and Arrays aren't allowed

Original source