Using Maps A simple map Hashtable n To
Using Maps
A simple map: Hashtable n To create a Hashtable, use: import java. util. *; Hashtable = new Hashtable(); n n To put things into a Hashtable, use: table. put(key, value); To retrieve a value from a Hashtable, use: value = table. get(key); 2
Example use of a Hashtable import java. util. *; public class Hashtable. User { } public static void main(String[] args) { Hashtable<String, String> table = new Hashtable<String, String>(); table. put("one", "un"); table. put("two", "deux"); table. put("three", "trois"); System. out. println("two -> " + table. get("two")); System. out. println("deux -> " + table. get("deux")); } two -> deux -> null 3
Hashtable constructors n n Hashtable() n Constructs a new, empty Hashtable with a default capacity (11) and default load factor (0. 75). Hashtable(int initial. Capacity) n Constructs a new, empty Hashtable with the specified initial capacity and the default load factor (0. 75). Hashtable(int initial. Capacity, float load. Factor) n Constructs a new, empty Hashtable with the specified initial capacity and the specified load factor. Hashtable(Map t) n Constructs a new Hashtable with the same mappings as the given Map. 4
Which constructor should you use? n This is basically a question of efficiency n n A hash table that is mostly empty wastes space If a hash table is nearly full, some searches may take a very long time The initial capacity of a hash table is the number of entries that it can hold initially The load factor is a measure of how full it is n n n A load factor of 75% is usually a good compromise If the table gets fuller than the load factor, Java creates a new, larger hash table and rehashes everything Rehashing is an expensive operation 5
Hashtable constructors (again) n n Hashtable() n Use if the default values are good enough Hashtable(int initial. Capacity) n Use if you have some idea how many entries to expect n Try to ensure it won’t be more than 75% full n If space is not an issue, double or triple the size Hashtable(int initial. Capacity, float load. Factor) n Use if you are trying to be super efficient n Requires careful experimentation and tuning Hashtable(Map<? extends K, ? extends V> t) n Use to make a Hashtable from some other map n Initial capacity = 2*(size of t), load factor = 0. 75 6
The Collections framework Collection Set Map List Sorted. Map Hashtable Sorted. Set n Hashtable is an old (pre-Collections) class n Hashtable has been retrofitted to implement the Map interface 7
The Map interface I n Basic operations: n n n V put(K key, V value) n Returns the previous value associated with key, or null if there was no previous value V get(Object key) n Returns null if the key was not found n A return value of null may not mean the key was not found (some implementations of Map allow null keys and values) Tests: n n boolean contains. Key(Object key) boolean contains. Value(Object value) n Warning: probably requires linear time! boolean is. Empty() boolean equals(Object o) n Returns true if o is also a map and has the same mappings 8
The Map interface II n Optional operations: n n n V put(K key, V value) n (So you could implement an immutable map) void put. All(Map t) n Adds the mappings from t to this map void clear() Object remove(Object key) n Returns the value that was associated with the key, or null Other: n n int size() n Returns the number of key-value mappings int hash. Code() n Returns a hash code value for this map 9
Optional operations n n Question: How can a method declared in an interface be optional? Answer: you have to implement it, but the implementation may be something like this: public void remove(Object key) throws Unsupported. Operation. Exception { throw new Unsupported. Operation. Exception(); } n In fact, Hash. Map extends Abstract. Map, which provides many of the map operations, and implements the optional operations exactly this way 10
Map views n Set<K> key. Set() n n Collection<V> values() n n n Returns a set view of the mappings contained in this map. A view is dynamic access into the Map n n n Returns a collection view of the values contained in this map Can’t be a set—keys must be unique, but values may be repeated Set<Map. Entry<K, V>> entry. Set() n n Returns a set view of the keys contained in this map. If you change the Map, the view changes If you change the view, the Map changes The Map interface does not provide any Iterators n However, there are iterators for the above Sets and Collections 11
Map. Entry: Interface for entry. Set elements n n n public interface Entry { K get. Key( ); V get. Value( ); V set. Value(V value); } This is a small interface for working with the Collection returned by entry. Set( ) Can get elements only from the Iterator, and they are only valid during the iteration 12
Constructors n Map is an interface, so it cannot require any constructors n However, Java always supplies: n n n A no-argument constructor for each Map type A constructor that takes a Map argument, and copies its keyvalue pairs into the new Map If you ever implement your own Map class, you should define these constructors n Defining your own Map class is easy: class My. Map implements Map {. . . } n There are, however, a lot of methods to implement 13
Hazards I n n In order for a Hashtable to work correctly, n equals must be defined properly on the keys n hash. Code must be defined properly on the keys This is not a problem if you use Strings for the keys (this is extremely common) If you use objects of some other class as your keys, you must make sure equals and hash. Code are properly defined Note: equals and hash. Code are properly defined for all of Java’s Maps; it’s the keys that you need to be careful with 14
Hazards II n n You should use immutable objects (like Strings) as keys If you put a value into a hash table with a mutable key, and you change the key, what happens? n n Answer: Nothing good! Special case #1: A map may not contain itself as a key Special case #2: A map may contain itself as a value, but equals and hash. Code are no longer well-defined These special cases are really weird and you will probably never get anywhere near them 15
From Hashtables to Hash. Maps n n Hashtable has been around a long time, but Hash. Map is new with Java 1. 2 So why am I teaching you the old stuff? n n n Actually, except for the constructors, I’ve been talking about the Map interface, which both Hashtable and Hash. Map implement Both are cloneable (more on this later) and serializable Differences: n n is synchronized; Hash. Map is not Hash. Map permits null values and (one) null key; Hashtable does not Hashtable 16
synchronized n Java supports multiple Threads n n n A Thread is an execution sequence Having multiple Threads means that Java appears to be doing many different things all at the same time Threads can interfere with each other unless they are carefully synchronized (prevented from both using the same data at the same time) This can be an issue with GUIs, which run in a different Thread from the rest of the program If you use a hash table from an event handler, use a Hashtable (which is synchronized) instead of a Hash. Map (which is not) 17
Copying objects • In Java, you seldom copy objects, you just copy references to objects Person mary = new Person("Mary", 21); Person john = new Person("John", 23, mary); mary. set. Spouse(john); Person jack = john; jack. name = "Jack"; n n john jack "Jack" "John" 23 "Mary" "John" 21 Suppose, however, that you really do want to make a copy; how do you do it? Answer: you clone the object 18
The Cloneable interface n Cloneable, like Serializable, is a marker interface: it doesn't require n any methods It does, however, allow you to use the clone method n class Person implements Cloneable {. . . } n n n . . . Person jack = john. clone(); clone() makes a shallow copy If you want a deep john copy, you have to write a lot more code jack Avoid making copies if possible; it’s not easy and it’s expensive "John" 23 "Mary" "John" 21 "John" 23 19
Copy constructors n n n Rather than use cloneable, it’s usually better to write a copy constructor—a constructor that takes an object as a parameter and makes another object just like it Example: Person jack = new Person(john); There is nothing magic about a copy constructor—it’s up to you to make a deep copy rather than a shallow copy Person (Person original) { this. name = original. name; this. spouse = new Person(original. spouse); this. spouse = this; // why? } Does this actually work? 20
The Sorted. Map interface n n n A hash table keeps elements in an (apparently) random order Sometimes you want the keys of a map to be in sorted order (e. g. phone book, dictionary) A map can be implemented with a hash table, but it doesn’t have to be The Sorted. Map interface implements the Map interface and provides additional methods For efficiency, you want an implementation that keeps its elements in some kind of order 21
Requirements for Sorted. Map n A Sorted. Map keeps its elements in the order of increasing key values n Therefore, it must be possible to sort the keys! n This means: n n The keys must be objects of a type that implement the Comparable interface (or be given a Comparator) Keys must be mutually comparable (e. g. you can’t compare a String to a Button) The ordering must be consistent with equals All implementations of Sorted. Map should supply four constructors n We’ll see an example of these shortly 22
Sorted. Map Methods I n Comparator<? super K> comparator() n n K first. Key() n n Returns the comparator associated with this sorted map, or null if it uses its keys' natural ordering. Returns the first (lowest) key currently in this sorted map. K last. Key() n Returns the last (highest) key currently in this sorted map. 23
Sorted. Map Methods II n Sorted. Map<K, V> head. Map(K to. Key) n n Sorted. Map<K, V> sub. Map(K from. Key, K to. Key) n n Returns a view of the portion of this sorted map whose keys are strictly less than to. Key. Returns a view of the portion of this sorted map whose keys range from. Key, inclusive, to to. Key, exclusive. Sorted. Map<K, V> tail. Map(K from. Key) n Returns a view of the portion of this sorted map whose keys are greater than or equal to from. Key. 24
The Tree. Map class n n Tree. Map implements Sorted. Map Tree. Map is the only implementation that Java provides for Sorted. Map Question: Since there’s only one implementation, why bother to have a separate interface? Answer: To give you the flexibility to define additional kinds of sorted map, if you wish to n You probably won’t—but the flexibility is there 25
Tree. Map constructors n Tree. Map() n n Tree. Map(Comparator<? super K> c) n n Constructs a new, empty map, sorted according to the given comparator. Tree. Map(Map<? extends K, ? extends V> m) n n Constructs a new, empty map, sorted according to the keys' natural order. Constructs a new map containing the same mappings as the given map, sorted according to the keys' natural order. Tree. Map(Sorted. Map<K, ? extends V> m) n Constructs a new map containing the same mappings as the given Sorted. Map, sorted according to the same ordering. 26
Quick summary n Interfaces (cannot instantiate): n n n Classes (can instantiate): n n Hashtable Hash. Map Tree. Map As always, it’s best to avoid exposing the implementation; hence: n n Map Sorted. Map Serializable Cloneable Map<String, String> my. Map = new Hash. Map<String, String>(); But probably not: n Map<String, String> my. Map = new Tree. Map<String, String>(); 27
Sets n We’ve talked about Sets before, and you probably remember the basic operations: n n n int size( ); boolean is. Empty( ); boolean contains(Object e); boolean add(E e); boolean remove(Object e); Iterator<E> iterator( ); However, Set is an interface, not a class There are two supplied implementations: Hash. Set (for when you don’t care about the order of elements) and Tree. Set (for when you do) 28
The End 29
- Slides: 29