CSC207 Software Design
Lectures
Maps

Maps

Also called hashes, dictionaries, and associative arrays

A list is a function from 0...N-1 to values

A map is a function from arbitrary keys to values

Each key can appear at most once, and has only one value

Usually use strings as indices

Like a phone book

Example: Phone Numbers

As a list:

[["Darwin", "748-2797"], ["Newton", "748-9901"], ["Turing", "745-0396"]]

As a map:

{"Newton"="748-9901", "Darwin"="748-2797", "Turing"="745-0396"}

Note: maps are unordered

Unlike a phone book

Ensures fast access

Interface and Implementation

Generic properties of maps defined by interface java.util.Map

A contract that other classes have to satisfy

Several standard classes implement this interface in different ways

HashMap and TreeMap are the most popular

Neither is best in all situations

(Almost) always declare variables/parameters to have type Map

Putting Values In

Add values to a dictionary using put()

First argument is the key

Second is the value

Both must be objects

null is allowed

toString() returns "{k1=v1, k2=v2}"

Birthday Example

public class Birthday {
    public static void main(String[] args) {
        Map m = new HashMap();
        m.put("Newton", new Integer(1642));
        m.put("Darwin", new Integer(1809));
        System.out.println(m);
    }
}
{Darwin=1809, Newton=1642}

Getting Values Out

Get value associated with key using get()

One argument: the key

Returns an object

System.out.println(m.get("Darwin"));
1809
Integer bday = (Integer)m.get("Newton");
System.out.println(bday)
1642

How do you know if a key is there?

System.out.println(m.containsKey("Turing"));
false

Iterating

Usually iterate by getting the set of keys, and iterating over that

Set keys = m.keySet();
Iterator i = keys.iterator();
while (i.hasNext()) {
    Object key = i.next();
    System.out.println(key + "=>" + m.get(key));
}
Darwin=>1809
Newton=>1642

Lookup Tables

public static String[] Data = {
    "Newton ike@math.cambridge.ac.uk",
    "Darwin cd@evolution.org"
};

public static void main(String[] args) {
    Map m = new HashMap();
    for (int i=0; i<Data.length; ++i) {
        String[] fields = Data[i].split(" ");
        m.put(fields[0], fields[1]);
    }
    System.out.println("Darwin: " + m.get("Darwin"));
    System.out.println("Newton: " + m.get("Newton"));
    System.out.println("Turing: " + m.get("Turing"));
}
Darwin: cd@evolution.org
Newton: ike@math.cambridge.ac.uk
Turing: null

Counting

public static void main(String[] args) {
    String[] data = "Be Mg Mg Ca Be Mg".split(" ");
    Map m = new HashMap();
    for (int i=0; i<data.length; ++i) {
        if (m.containsKey(data[i])) {
            Integer tmp = (Integer)m.get(data[i]);
            m.put(data[i], new Integer(tmp.intValue() + 1));
        }
        else {
            m.put(data[i], new Integer(1));
        }
    }
    System.out.println(m);
}
{Ca=1, Mg=3, Be=2}

Inverting

public static void main(String[] args) {
    Map byName = new HashMap();
    byName.put("Darwin", "748-2797");
    byName.put("Newton", "748-9901");
    byName.put("Turing", "745-0396");
    Map byPhone = new HashMap();
    Iterator i = byName.entrySet().iterator();
    while (i.hasNext()) {
        Map.Entry e = (Map.Entry)i.next();
        byPhone.put(e.getValue(), e.getKey());
    }
    System.out.println(byPhone);
}
{748-2797=Darwin, 745-0396=Turing, 748-9901=Newton}

Caution #1

Do not change keys once they are in the map

Can't change strings

But can change sets, lists, etc.

What happens?

Entry is now filed in the wrong location

May not be found the next time you do a search

(Very) hard to track down

Caution #2

If you override equals(), override hashCode() as well

a == b is true if and only if a and b are the same object

a.equals(b) checks to see if a and b have the same value

If a.equals(b), then a.hashCode() and b.hashCode() must return the same value

Why?

Because that's how maps do lookups


$Id: map.html,v 1.1.1.1 2004/01/04 05:02:31 reid Exp $