CS 1301 * Ch 6, Handout 1

advertisement
CS 1302 – Ch 21, Sets & Maps
These notes cover Sections 5 and 6 of Chapter 21.
Section 21.5 – Maps
1. A Map stores key/value pairs. The keys are like indexes used to access the values. A List uses an integer
index to reference the items in the list. In a Map, the keys can be any objects. The
2. The Map Interface:
java.util.Map<K, V>
+clear(): void
Removes all mappings from this map.
+containsKey(key: Object): boolean
Returns true if this map contains a mapping for the
specified key.
+containsValue(value: Object): boolean Returns true if this map maps one or more keys to the
specified value.
+entrySet(): Set
Returns a set consisting of the entries in this map.
+get(key: Object): V
Returns the value for the specified key in this map.
+isEmpty(): boolean
Returns true if this map contains no mappings.
+keySet(): Set<K>
Returns a set consisting of the keys in this map.
+put(key: K, value: V): V
Puts a mapping in this map.
+putAll(m: Map): void
Adds all the mappings from m to this map.
+remove(key: Object): V
Removes the mapping for the specified key.
+size(): int
Returns the number of mappings in this map.
+values(): Collection<V>
Returns a collection consisting of the values in this map.
1
3. The Map hierarchy:
«interface»
java.util.Map<K, V>
«interface»
java.util.AbstractMap<K, V>
java.util.SortedMap<K, V>
+firstKey(): K
java.util.HashMap<K, V>
+lastKey(): K
+comparator(): Comparator<? super K>)
+HashMap()
+headMap(toKey: K): SortedMap
+HashMap(m: Map)
+tailMap(fromKey: K): SortedMap
java.util.LinkedHashMap<K, V>
+LinkedHashMap()
java.util.TreeMap<K, V>
+LinkedHashMap(m: Map)
+TreeMap()
+LinkedHashMap(initialCapacity: int,
loadFactor: float, accessOrder: boolean)
+TreeMap(m: Map)
+TreeMap(c: Comparator<? super K>)
4. Concrete Map implementations:
a. HashMap – keys have no ordering.
b. LinkedHashMap – Keys are ordered according to the order they were inserted.
c. TreeMap – Keys are sorted (natural ordering, Comparable, or Comparator)
5. Advanced – The entries in a LinkedHashMap can also be accessed in the order in which they were last
accessed, from least recently accessed to most recently (access order). This can be used in an LRU
(Least Recently Used) cache. The constructor is:
LinkedHashMap(initialCapacity, loadFactor, true).
Section 21.6 – Case Study: Occurences of Words
Study the example from the text carefully.
Sections 21.7 – Singleton & Unmodifiable Collections & Maps
Omit
2
Ch 20 & 21, JCF Summary
3
4
java.util.Collections
List
+sort(list: List): void
Sorts the specified list.
+sort(list: List, c: Comparator): void
Sorts the specified list with the comparator.
+binarySearch(list: List, key: Object): int
Searches the key in the sorted list using binary search.
+binarySearch(list: List, key: Object, c:
Comparator): int
Searches the key in the sorted list using binary search
with the comparator.
+reverse(list: List): void
Reverses the specified list.
+reverseOrder(): Comparator
Returns a comparator with the reverse ordering.
+shuffle(list: List): void
Shuffles the specified list randomly.
+shuffle(list: List): void
Shuffles the specified list with a random object.
+copy(des: List, src: List): void
Copies from the source list to the destination list.
+nCopies(n: int, o: Object): List
Returns a list consisting of n copies of the object.
+fill(list: List, o: Object): void
Fills the list with the object.
+max(c: Collection): Object
Returns the max object in the collection.
+max(c: Collection, c: Comparator): Object Returns the max object using the comparator.
+min(c: Collection): Object
Collection
Returns the min object in the collection.
+min(c: Collection, c: Comparator): Object Returns the min object using the comparator.
+disjoint(c1: Collection, c2: Collection):
boolean
Returns true if c1 and c2 have no elements in common.
+frequency(c: Collection, o: Object): int
Returns the number of occurrences of the specified
element in the collection.
Arrays Class
Methods
Modifier and Type
Method and Description
static <T> List<T>
asList(T... a)
Returns a fixed-size list backed by the specified array.
static int
binarySearch(double[] a, double key)
Searches the specified array of doubles for the specified value using the binary search
algorithm.
static <T> int
binarySearch(T[] a, T key, Comparator<? super T> c)
Searches the specified array for the specified object using the binary search algorithm.
static float[]
copyOf(float[] original, int newLength)
Copies the specified array, truncating or padding with zeros (if necessary) so the copy has
the specified length.
static double[]
copyOfRange(double[] original, int from, int to)
Copies the specified range of the specified array into a new array.
static void
fill(float[] a, float val)
Assigns the specified float value to each element of the specified array of floats.
static void
sort(double[] a)
Sorts the specified array into ascending numerical order.
static <T> void
sort(T[] a, Comparator<? super T> c)
Sorts the specified array of objects according to the order induced by the specified
comparator.
static String
toString(double[] a)
Returns a string representation of the contents of the specified array.
5
HashSet & HashMap with Custom Objects (Advanced)
1. If you want to use HashSet with custom objects then the custom class must override both the equals
and hashCode methods. The Java API says that if two objects are to be considered equal
(a.equals(b)==true) then their hashcodes must be equal (a.hashCode()==b.hashCode()). Note, this does
not say that two objects that have the same hashcode are equal. The signature for the two methods
are:
public boolean equals( Object o )
public int hashCode()
We already know what the equals method is used to enforce logical equality. For instance, two
Employees are equal, for instance, if and only if they have the same SSN.
2. The hashCode method is a bit more involved to explain. You will study hashing in detail in the next
course (CS 3410). For now, we say that the hashCode method returns aninteger that represents the
location of the object. The HashSet class uses the hashcode to find an object in a set. The operation
works something like this: in the course of doing certain operations (add, contains) if the HashSet class
determines that two objects have the same hashcode, then it calls equals to see if the objects are
really the same.
3. For instance, suppose we are using a HashSet to hold Employee objects. When we add an Employee to
the HashSet, the Employee’s hashcode is used to store the object, like an index in an array. For
example, an Employee object may have a hashcode of 48, so the HashSet add method would put this
object in the 48th position in an array. Later, when you want to call the contains or remove method
with that Employee object, the code retrieves the hashcode (48) for the object and then finds the
object in position 48. The situation is identical with HashMap if we want to use custom objects for the
keys or if we want to use the containsValue method when the values are custom objects.
4. So, how do we override the hashcode method? We will show a simple approach here and again in the
HashMap section. You will consider this in more detail in CS 3410. To override hashcode effectively
takes a much deeper understanding. Some further explanation and guidance can be found here:
http://tutorials.jenkov.com/java-collections/hashcode-equals.html
http://www.ibm.com/developerworks/library/j-jtp05273/
http://www.javaworld.com/article/2076332/java-se/how-to-avoid-traps-and-correctly-overridemethods-from-java-lang-object.html?page=2
http://www.javamex.com/tutorials/collections/hash_function_guidelines.shtml
6
5. Example – The class below only implements the equals method, but not the hashCode method.
Code – Incorrect, only overrides the equals method.
class EmployeeIncorrect
{
private String lName;
private String fName;
public EmployeeIncorrect( String lName, String fName )
{
this.lName = lName;
this.fName = fName;
}
public String getLastName() { return lName; }
public String getFirstName() { return fName; }
public boolean equals(Object o)
{
EmployeeIncorrect e = (EmployeeIncorrect)o;
return ( this.getLastName().equals(e.getLastName()) ) &&
( this.getFirstName().equals(e.getFirstName()) );
}
}
So, we create two Employees that are equal, but they both get added to the set. This is because the
add method calls the hashCode method on each object and they are both different, so equals never
gets called. The hashCode method that is called is the one implemented in the Object class which
usually uses the address of the object to compute its hashcode. Usually this unique.
Code
Set<EmployeeIncorrect> set = new HashSet<EmployeeIncorrect>();
Output
EmployeeIncorrect e1 = new EmployeeIncorrect("Jones", "Hugh" );
EmployeeIncorrect e2 = new EmployeeIncorrect("Jones", "Hugh" );
System.out.println( set.add( e1 ) );
System.out.println( set.add( e2 ) );
true
true
System.out.println( set );
[Hugh Jones,
Hugh Jones]
7
6. Example – Here, we also override the hashCode method in the Employee class.
Code
class Employee
{
private String lName;
private String fName;
public Employee( String lName, String fName )
{
this.lName = lName;
this.fName = fName;
}
public String getLastName() { return lName; }
public String getFirstName() { return fName; }
public String toString()
{
return String.format("%s %s", getFirstName(), getLastName() );
}
public boolean equals(Object o)
{
Employee e = (Employee)o;
return ( this.getLastName().equals(e.getLastName()) ) &&
( this.getFirstName().equals(e.getFirstName()) );
}
public int hashCode()
{
int x = lName.hashCode();
int y = fName.hashCode();
int z = 23*x + 7*y;
return z;
}
}
Some test code now shows that the duplicate object will not be added
Code
Set<Employee> set2 = new HashSet<Employee>();
Output
Employee e3 = new Employee("Jones", "Hugh" );
Employee e4 = new Employee("Jones", "Hugh" );
System.out.println( set2.add( e3 ) );
System.out.println( set2.add( e4 ) );
true
false
System.out.println( set2 );
[Hugh Jones]
8
Download