Week1 Map
Week1 Map
Java 5.0 introduced (at least) three language features This automatically creates an Integer object:
http://java.sun.com/j2se/1.5.0/docs/guide/language/ Integer i1 = 3; // autoboxing
int i2 = i1; // unboxing
Autoboxing/unboxing
Automatically converts primitives (such as int) to wrapper classes (such as
Integer) Note that this doesn’t have a call to intValue:
Enhanced for loop /** Return the sum of the elements in a */
New concise syntax for iterating through a collection public static int sum(Integer[] a) {
int result = 0;
Generics
for (int i = 0; i != a.length; i++) {
Constrain what kinds of objects collections such as Vectors, ArrayLists, result += a[i]; // unboxing
Maps, and Sets can contain }
Removes need for annoying typecasts and instanceof checks return result;
}
Removes need for indexing: Another example, using an ArrayList instead of an array (this is almost right – we
will correct it in a few slides from now):
/** Return the sum of the elements in a */ /** Return the sum of the elements in a */
public static int sum(Integer[] a) { public static int sum(ArrayList a) {
int result = 0; int result = 0;
for (Integer i : a) { for (Integer v : a) {
result += v;
result += i;
}
} return result;
return result; }
} The old way:
Iterator iter = a.iterator();
while (iter.hasNext()) {
(Sure beats the old way, doesn’t it?) Integer v = (Integer) iter.next();
…
1
Java: generics Java: generics
Iteration using generics, autoboxing, and the new for loop is beautiful (to New safety and ease:
a geek): Can only call sum with lists that contain only Integers
/** Return the sum of the elements in a */
No need for a typecast or a call to intValue
public static int sum(ArrayList<Integer> a) {
No need to create an Iterator
int result = 0;
for (Integer v : a) {
result += v;
}
return result;
}
2
A common problem Solution: maps
Want to associate pairs of values where one of the A list is a function from 0..N-1 to values
values is guaranteed to be unique As a list of pairs:
Example: match people with their favourite chocolate [["Darwin", "Snickers"], ["Newton",
bar "Mars Bar"], ["Turing", "Kit Kat"]]
"Michelle" => "Coffee Crisp" A map is a function from keys to values
"Paul" => "Kit Kat" As a map:
How would we do this with lists? {"Newton"="Mars Bar", "Darwin"=
"Snickers", "Turing"="Kit Kat"}
Note: Maps are unordered
Each key can appear at most once and has only one Generic properties of maps defined by interface
value java.util.Map<K, V>: a Java interface that maps keys
of type <K> to values of type <V>
Also called hashes (Perl), dictionaries (Python), and
associative arrays (ancient) Classes implementing Map:
HashMap, TreeMap
Take CSC263H to learn how to choose
3
Putting values in Birthday example
4
Iterate using new for loop Lookup table
public static void main(String[] args) {
Or, using the new for loop:
Map m = new HashMap();
Set<String> keys = m.keySet(); for (int i = 0; i < data.length; ++i) {
for (String key : keys) { String[] fields = data[i].split(" ");
System.out.println( m.put(fields[0], fields[1]);
}
key + "=>" + m.get(key));
} System.out.println("Darwin: " + m.get("Darwin"));
System.out.println("Newton: " + m.get("Newton"));
System.out.println("Turing: " + m.get("Turing"));
}
Counting Inverting
public static void main(String[] args) { public static void main(String[] args) {
String[] data = "Be Mg Mg Ca Be Mg".split(" "); Map byName = new HashMap();
Map<String, Integer> m = new HashMap<String, Integer>(); byName.put("Darwin", "748-2797");
5
Inverting (Java 5.0) Caution #1
public static void main(String[] args) {
Do not modify key objects: location in map is
Map<String, String> byName =
new HashMap<String, String>();
computed from key contents ("hash code")
byName.put("Darwin", "748-2797"); Can't change Strings
byName.put("Newton", "748-9901"); But, you can change sets, lists, etc.
Map<String, String> byPhone =
What happens if you do?
new HashMap<String, String>();
for (Map.Entry<String, String> e : byName.entrySet()) { Entry is now filed in the wrong location
byPhone.put(e.getValue(), e.getKey()); May not be found the next time you search
} Very hard to track down
System.out.println(byPhone);
} {748-2797=Darwin, 748-9901=Newton}
If you override method equals, override hashCode There are three file-like objects associated with every
as well program:
a == b iff a and b are the same object stdin – standard input, usually from the keyboard
a.equals(b) checks to see if a and b refer to objects (System.in)
that have the same value
stdout – standard output, usually to the screen
If a.equals(b), then a.hashCode() and (System.out)
b.hashCode() must return the same value
stderr – standard error, usually to the screen
Why? Because that's how maps do lookups (System.err)
6
Reminder: I/O Trick: reading from Strings
BufferedReader input;
We can use the same file abstraction to read from
input = new BufferedReader(new FileReader("filename"));
strings (and print to them):
input = new BufferedReader(new InputStreamReader(System.in)); input = new BufferedReader(
new StringReader("A string"));
String line;
while((line = input.readLine()) != null) { Primary advantage is for testing
// do something
}
We can keep all test code in a single file, but use the
same interfaces
It is a lot faster
You’ll see this technique used in E1