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 $