- Administrivia - Ice Cream! Friday, 12:30-2:00, FEC 141 - Demo programs available -- check the class web site - Lab sections: can anybody move to a different lab? ==================== - Quiz 1 ==================== - why am I asking you to implement the java.util.Map interface? What does it mean to implement an interface? And why do we have interfaces at all? - the hierarchy of design levels (lowest to highest): - language syntax/semantics (for, while, extends, throw, etc.) - programming idioms (how to write a for loop; how to open a file) - libraries/APIs (java.io, java.util, java.net) - patterns (model/view/controller, singleton, proxy, etc.) - principles (ex: parsimony, locality, abstraction, etc.) - language features often created to support higher-level design things - interfaces created to support: - Design principle #1: principle of abstraction -- only work with the relevant aspects of a thing; ignore stuff that's not immediately relevant. - in this case: we care about what a Map _does_ -- its _behavioral_contract_, not how it implements that contract - Design principle #2: centralized definition -- define a thing only once in a program; use a symbolic name to refer to it later. - example: definining constants public static final double PI=3.141592...; public static final String CMD_GO="Go"; refer later just to PI or CMD_GO, so that later we can change "Go" to "Allez" by making only one change in the program. - interface allows you to do the same thing with _types_: public Map dataStore=new MondoHashMap(); public List retrieve(Map m, String s) { List l=(List)m.get(s); } if we need to, we can later change "MondoHashMap()" to "HashMap()" or "TreeMap". Code will continue to work. - key idea is: interface tells you what a thing can _do_, but now how that thing is _implemented_. - allows the programmer to rely on a thing having a specific set of methods, but ignore how those methods actually work (abstraction) - also allows you to substitute one thing that obeys the interface for any other thing that obeys that interface - HINT: you can use this to test your code -- write one test program that works with general java.util.Map. Plug in java.util.HashMap into the test program to see what the JDK implementation does. Then plug in _your_ MondoHashMap into the test program to make sure that yours behaves the way that the "reference implementation" (java.util.HashMap) works. - Note: not allowed to use java.util.HashMap for your MondoHashMap or Moogle implementations, but you _are_ allowed to use it as a reference implementation for testing! - ok, so that's what an interface is _for_, how do we _do_ it? - simple answer: import java.util.Map; public class MondoHashMap implements Map { public Object get(Object key) { // your code to make get() work } public Object put(Object key, Object value) { // your code to make put() work } // etc... } - basically: just write method _bodies_ to fill out all of the method _signatures_ described in the java.util.Map spec. - Note: javac won't let you cut corners -- it will _insist_ that you provide implementations for _all_ of these. That's how it ensures you're meeting the interface contract. - Question: If you look in a theory/data structs textbook (e.g., CLRS), you find that they define a hash table as having the following operations: insert (put) search (get) delete (remove) But the java.util.Map spec contains _14_ methods. Why all the extras? - Question 2: theory texts spend a _lot_ of time on what makes a good hashing function. In this class, you can completely blow that off. Why?