QUESTIONS LAST TIME: - SiteRiter questions, Where do you put the state, Memory and pointer diagrams TODAY: - New TA! Lucas Nunno, FEC330B, Thu 4-5:30PM, Fri 1-2:30PM - More memory and pointer diagrams - The uber data structure PROJECT 1 STATUS DAY 20: - First project FINAL DELIVERABLE in progress! +---------------+ - Interim deliverable #2 ALL DONE | 3 DAYS 1 HOUR | - Interim deliverable #1 ALL DONE | REMAINING | +---------------+ SEEN ON THE INTERNETS: One Megabubble vetoes the 99%. PROJECT 1 QUESTIONS WHERE DO YOU PUT THE STATE? - 'State': Information to be remembered for later in the computation. = Always two basic questions about state: 1. LIFETIME: How long does it need to be remembered? 2. DIRECT ACCESS: Who most needs to get at it during its life? - Choices: 1. ARGUMENT TO OR LOCAL VARIABLE IN A METHOD Lifetime: Lives until the method finishes (by return or exception) Direct Access: Only within the method in which it's declared 2. PRIVATE NON-STATIC FIELD IN AN OBJECT Lifetime: Lives as long as the object lives Direct Access: Within all non-static methods of the object's class 3. PRIVATE STATIC FIELD IN A CLASS Lifetime: Lives 'forever' (as long as the class is accessible) Direct Access: Within all methods of the class, static and non-static 4. IN A DATA STRUCTURE (array, list, map, etc); which in turn is located in 1, 2, or 3. (Or 4, recursively, but ultimately 1-3). - Rule of thumb: Use the shortest-lived, least-accessible place sufficient for the needs of the particular state. - What about public fields? What about 'final' state? OBJECTS AND THEIR INTERACTIONS - Object-oriented programming is about building islands and bridges. - Actually it's about building blueprints for islands with bridges, _and_ building islands with bridges from the blueprints and connecting the islands to each other with the bridges. - Actually it's about building construction companies that know how to build islands with bridges, and having those companies build islands with bridges, and having the islands get connected to each other by the bridges. - Actually it's about... To have a clue what is going on, we need to be able to visualize the stages of construction, and draw maps of the resulting island chains.. - Lots of pictures for lots of purposes. E.g., UML class diagrams. - Basic: Memory and pointers diagrams => 'memory', places that information can be stored, represented by a box => 'pointers', memory that's treated as an address, represented by an arrow - Java uses memory and pointers in fixed ways. So the pictures have rules. JAVA'S USE OF MEMORY AND POINTERS - CARTOON VERSION There are two things in the Java universe VARIABLES and OBJECTS How do you tell them apart? VARIABLES have NAMES (and TYPES) OBJECTS have TYPES (but no NAMES) JAVA'S USE OF MEMORY AND POINTERS - CARTOON VERSION Two rules: (1) Memory contains variables, and objects, which are collections of variables. (2) A variable can contain either (2.1) A primitive value (int, short, char, byte, long, float, double), or (2.2) A null reference that isn't pointing anywhere, or (2.3) A reference pointing to an object. To draw a memory and pointers diagram: (1) Variables and objects are both drawn as boxes (WARNING! Confusion risk!) (2) A variable is drawn as a box (2.1) If the variable contains a primitive value, that value is drawn inside the box (2.2) If the variable contains a null reference, 'null' goes in the box (2.3) If the variable contains an object reference, an arrow is drawn, with its tail inside the box and its head on the object it refers to (3) An object is drawn as a stack of variables. VARIABLE OR OBJECT - JAVA'S USE OF MEMORY AND POINTERS - CARTOON VERSION i int i = 0; +----+ | 0| VARIABLE +----+ j Integer j = null; +----+ |null| VARIABLE +----+ k Integer k = +----+ new Integer(3); | | VARIABLE +--|-+ | Integer \---->+----------+ | 3 | OBJECT +----------+ MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. = 'Draw the memory and pointers diagram for this program: class Foo { .. public static void main(String[] args) { .. } .. }' MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. .. boolean foo = true; if (foo) { int bar = 12; System.out.println(2*bar); } short gah = 9; /* HERE */ gah foo .. +-----+ +-----+ | 9 | | true| +-----+ +-----+ MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. int foo = 3; String bar = "ha"; bar = "ah"+bar; /* HERE */ foo bar bar String +----+ +---------+ +-----+ +---------+ | 3 | | "ahha" | | ----->| | +----+ +---------+ +-----+ | "ahha" | | | | | | | +---------+ MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. r r r +----+ +----+ +----+ |null| | ------> (stuff) | |----> (stuff) +----+ +----+ +----+ COULD BE RIGHT COULD BE RIGHT DEFINITELY WRONG MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. a Foo a = new Foo(); +----+ Foo Foo b = a; | ------>+----+ /* HERE */ +----+ | .. | | | +----+ SO FAR SO GOOD.. MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. b a Foo a = new Foo(); +---+ +----+ Foo Foo b = a; | ------------->| ------>+----+ /* HERE */ +---+ +----+ | .. | | | +----+ TOTALLY BLOWN! MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. b a Foo a = new Foo(); +---+ Foo +----+ Foo Foo b = a; | ---->+----+ | ------>+----+ /* HERE */ +---+ | .. | +----+ | .. | | | | | +----+ +----+ ALSO WRONG! MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. b a Foo a = new Foo(); +---+ +----+ Foo Foo b = a; | ----\ | ------>+----+ /* HERE */ +---+ \ +----+ | .. | \----------------->| | +----+ OKAY! MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. b a Foo a = new Foo(); +---+ +----+ Foo Foo b = a; | ----\ | ------>+----+ /* HERE */ +---+ \ +----+ / | .. | \--------------/ | | +----+ ALSO OKAY! MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. b a Foo a = new Foo(); +---+ +----+ Foo Foo b = a; | ----\ | ---\ +----+ /* HERE */ +---+ \ +----+ -->| .. | \--------------/ | | +----+ ALSO ALSO OKAY! MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. b a Foo a = new Foo(); +---+ +----+ Foo Foo b = a; | ----\ | ------>+----+ /* HERE */ +---+ \ +----+ | .. | \-------------------> | +----+ WRONG AGAIN! YOU CAN ONLY POINT AT A WHOLE OBJECT, NOT AT A PIECE INSIDE! MEMORY AND POINTERS - A memory and pointers picture must be associated with a specific moment in the execution of the program. - A box for every primitive variable alive at that moment. Primitive variable boxes have no arrows into them or out of them. Instead they have their values inside them. = We can treat a String reference variable as if it was a primitive variable, even though it's really not. - A box for every reference variable alive at that moment. Reference variable boxes either have 'null' in them or have precisely one arrow coming out of them. = Reference variable boxes can never have any arrows pointing at them. - A box for every (user-created, relevant) Object alive at that moment. = With 'slots' (sub-boxes) inside for every non-static field in the object = And each slot is either a primitive variable box or a reference variable box. A slot CANNOT be a whole object! MEMORY AND POINTERS zot +---------+ Gah Foo Foo Bar | ---->+-------+ +------+ +------+ +------+ +---------+ | null| | true |<---\ | true | /--->| 1.34 | |-------| |------| | |------| | +------+ | 123| | 'd' | | | 'd' | | +-------+ |------| | |------| | | -----/ | -----/ POSSIBLE +------+ +------+ POSSIBLE POSSIBLE MEMORY AND POINTERS zot +---------+ Gah Foo Foo Bar | ---->+-------+ +------+ +------+ +------+ +---------+ | null| | true |<---\ | true | /--->| 1.34 | |-------| |------| | |------| | +------+ | 123| | 'd' | | | 'd' | | +-------+ |------| | |------| | | -----/ | -----/ POSSIBLE +------+ +------+ POSSIBLE POSSIBLE Foo +------------+ | true | |------------| | 'd' | |------------| |Bar | |+-------+ | || 1.34 | | |+-------+ | +------------+ WRONG! MEMORY AND POINTERS zot +---------+ Gah Foo Foo Bar | ---->+-------+ +------+ +------+ +------+ +---------+ | null| | true |<---\ | true | /--->| 1.34 | |-------| |------| | |------| | +------+ | 123| | 'd' | | | 'd' | | +-------+ |------| | |------| | | -----/ | -----/ POSSIBLE +------+ +------+ POSSIBLE POSSIBLE Foo +------------+ Foo | true | +------+ |------------| | true<-----\ | 'd' | |------| | |------------| | 'd' | | |Bar | |------| | |+-------+ | | -----/ || 1.34 | | +------+ |+-------+ | +------------+ WRONG! WRONG MEMORY AND POINTERS zot +---------+ Gah Foo Foo Bar | ---->+-------+ +------+ +------+ +------+ +---------+ | null| | true |<---\ | true | /--->| 1.34 | |-------| |------| | |------| | +------+ | 123| | 'd' | | | 'd' | | +-------+ |------| | |------| | | -----/ | -----/ POSSIBLE +------+ +------+ POSSIBLE POSSIBLE Foo +------------+ Foo Foo | true | +------+ +------+ |------------| | true<-----\ | true |<---\ | 'd' | |------| | |------| | |------------| | 'd' | | | 'd' | | |Bar | |------| | |------| | |+-------+ | | -----/ | |---/ || 1.34 | | +------+ +------+ |+-------+ | +------------+ WRONG! WRONG WRONG MEMORY AND POINTERS zot +---------+ Gah Foo Foo Bar | ---->+-------+ ?-->+------+ +------+ +------+ +---------+ | null| | true |<---\ | true | /--->| 1.34 | |-------| |------| | |------| | +------+ | 123| | 'd' | | | 'd' | | +-------+ |------| | |------| | | -----/ | -----/ POSSIBLE +------+ +------+ POSSIBLE POSSIBLE Foo +------------+ Foo Foo Foo | true | +------+ +------+ +------+ |------------| | true<-----\ | true |<---\ | true | | 'd' | |------| | |------| | |------| |------------| | 'd' | | | 'd' | | | 'd' | |Bar | |------| | |------| | |------| |+-------+ | | -----/ | |---/ | ----\ || 1.34 | | +------+ +------+ +------+ | |+-------+ | v +------------+ null WRONG! WRONG WRONG WRONG MEMORY AND POINTERS - BLOWOUT! class Test { c (Test) args String[] private static int c = 0; +------+ +-------+ +------+ private int x = ++c; | 2 | | ------->| | private char y = 'd'; +------+ +-------+ | | private Test t; i j | ? | public static void main(String[] args) { +-----+ +-------+ | | /* HERE0 */ | 7 | | 7 | | | int i = 7; +-----+ +-------+ | | int j = i; /* HERE1 */ | | k b | | int k = 9; a +-----+ +------+ | | Integer m = k; /* HERE2 */ +-----+ | 9 | | | | +------+ |null | +-----+ +-|----+ Test a = new Test();/* HERE3 */ +-----+ Test | Test b = new Test();/* HERE4 */ +--------+<----/ a.t = b; /* HERE5 */ |x: 1 | b = a; /* HERE6 */ |--------| a = null; /* HERE7 */ |y: 'd' | b.t = null; /*HERE8*/ } |--------| } |t: null | +--------+ MAP - THE UBER DATASTRUCTURE MAP - THE UBER DATASTRUCTURE - Array: Go from a subset of int (an index) to some kind of Object Object[] array = new Object[MAX_SIZE]; int index = someMethod(); Object value = array[index]; MAP - THE UBER DATASTRUCTURE - Array: Go from a subset of int (an index) to some kind of Object Object[] array = new Object[MAX_SIZE]; int index = someMethod(); Object value = array[index]; - Map: Go from an Object (a 'key') to some kind of Object (a 'value') ..PSEUDOCODE.. Map map = new Map(); Object key = someMethod(); Object value = someOtherMethod(); map.put(key,value); if (map.containsKey(key)) System.out.println("value of "+key+" is "+map.get(key)); ... MAP - THE UBER DATASTRUCTURE - Array: Go from a subset of int (an index) to some kind of Object Object[] array = new Object[MAX_SIZE]; int index = someMethod(); Object value = array[index]; - Map: Go from an Object (a 'key') to some kind of Object (a 'value') ..PSEUDOCODE.. Map map = new Map(); Object key = someMethod(); Object value = someOtherMethod(); map.put(key,value); if (map.containsKey(key)) System.out.println("value of "+key+" is "+map.get(key)); ... -> Except: Map isn't a class, it's an interface.. http://docs.oracle.com/javase/6/docs/api/java/util/Map.html So we can't instantiate it directly. -> Different ways of implementing Map provide different performance tradeoffs. MAP - THE UBER DATASTRUCTURE - TYPES OF MAPS All Known Implementing Classes: AbstractMap, Attributes, HashMap, Hashtable, IdentityHashMap, RenderingHints, TreeMap, WeakHashMap MAP - THE UBER DATASTRUCTURE - TYPES OF MAPS All Known Implementing Classes: AbstractMap, Attributes, HashMap, Hashtable, IdentityHashMap, RenderingHints, TreeMap, WeakHashMap (Actually, that was from Java 1.4.2. Now it's like: All Known Implementing Classes: AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap ) MAP - THE UBER DATASTRUCTURE - TYPES OF MAPS All Known Implementing Classes: AbstractMap, Attributes, HashMap, Hashtable, IdentityHashMap, RenderingHints, TreeMap, WeakHashMap (Actually, that was from Java 1.4.2. Now it's like: All Known Implementing Classes: AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap ) But still: -> The most important ones are HashMap and TreeMap ('Hashtable' is mostly like a Good Olde Tymey HashMap. Use HashMap.) HASH TABLES Goal Store and access associations between names and values. (Or just fast name lookup, if no value). Seeking 'nearly constant time' accessing in terms of number of name-value associations stored. HASH TABLES Goal Store and access associations between names and values. (Or just fast name lookup, if no value). Seeking 'nearly constant time' accessing in terms of number of name-value associations stored. How? - Linked lists at best O(n) to access an arbitrary element - Trees at best O(log n) " " - Array accessing is O(1) " " HASH TABLES Goal Store and access associations between names and values. (Or just fast name lookup, if no value). Seeking 'nearly constant time' accessing in terms of number of name-value associations stored. How? - Linked lists at best O(n) to access an arbitrary element - Trees at best O(log n) " " - Array accessing is O(1) " " -> So use an array But accessing an array requires an array index, some kind of integer, to specify which arbitrary element. - But, a (general-purpose) 'name', whatever that is, isn't always going to be an integer. - Idea: Think of some way, some kind of 'hashing function' to mash up a name and turn it into an integer, then use that integer as an array index. A 'hashCode' or something..