Sunday, July 21, 2013

Java Collections Framework Part 5 - Maps

This is the sixth part of the tutorial, and this link goes to the previous post java collections framework part 4


A Map implements the java.util.Map interface, this interface doesn't extends from the Collection interface. A map is a collection of key-value mappings, they don't allow duplicate keys and like Sets, maps rely on the equals() method to determine whether two keys are the same or different.

Maps do not have order but some implementations are sorted like the TreeMap.

Maps like the Collection interface have methods for adding and removing elements, querying collection contents, and providing different views of the contents of a collection, and some of this methods are:

V put(K key, V value): Add or replace a key-value association, returns the old value (may be null) if the key was present; otherwise returns null.
void putAll(Map<? extends K,? extends V> m): Adds each of the key-value associations in the supplied map into the receiver.
void clear(): Removes all associations from this map.
V remove(Object key): Removes the association, if any, with the given key; returns the value with which it was associated, or null.
V get(Object k): Returns the value corresponding to k, or null if k is not present as a key.
boolean containsKey(Object k): Returns true if k is present as a key.
boolean containsValue(Object v): Return true if v is present as a value.
int size(): Returns the number of mappings.
boolean isEmpty(): Returns true if there are no mappings.
Set<Map.Entry<K, V>> entrySet(): Returns a Set view of the associations.
Set<K> keySet(): Return a Set view of the keys
Collection<V> values(): Return a Collection view of the values

The java.util.HashMap class is an implementation of the Map interface. HashMap it keeps its elements unsorted and unordered.

You should know that HashMap allows one null key and multiple null values in a collection.


In the previous example a HashMap of Integers as keys and Strings as values was created, five elements were added and then an element was added again replacing its previous value. The output of the example should be:

Map:{[1, one] [2, two] [3, three-again] [4, four] [5, five] }

The java.util.Hashtable class is also an implementation of the Map interface and it is almost identical
to the HashMap class but it is synchronized so it performs slower than HashMap and another difference is that Hashtable doesn't let you have anything that's null.

The java.util.LinkedHashMap class extends from the HashMap class and therfore is an Implementation of the Map interface, and as the LinkedHashSet class the LinkedHashMap it maintains insertion order (or, optionally, access order). Access ordered is defined by the argument of of the constructor:

public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)

A value false will give an insertion-ordered map, if order constructor is used to create the LinkedHashMap by default it would be an insertion-ordered map.


The output of the example should be the following:
Map { [1-1] [2-2] [3-3] [4-4] [5-5] }

Changing the the iteration order for an access order in the previous example:

Notice that after adding the elements an access to the element “1” is done with this the iteration order is changed and the output should be the following:
Map Keys { [2] [3] [4] [5] [1] }
Also notice that the output format has changed and now just the keys are printed, this is because if the element is obtained inside the iteration loop a ConcurrentModificationException would arise because the iteration order is changed , and this can not be done while the map is iterated. So be careful when the Map is in this mode.


The class java.util.TreeMap is an implementation of the Map interface, it also implements the
java.util.NavigableMap and java.util.SortedMap interfaces. This collection is pretty similar to TreeSet, it is an sorted collection and guarantees that the keys will be in ascending order, according to their natural order, or by a Comparator provided at map creation time, depending on which constructor is used.

The TreeMap class implements methods that help navigate the map, and some of these methods are:

K ceilingKey(key): Returns the lowest key >= key
K higherKey(key): Returns the lowest key > key
K floorKey(key): Returns the highest key <= key
K lowerKey(key): Returns the highest key < key
Map.Entry<K,V> pollFirstEntry(): Returns and removes the first key-value pair
Map.Entry<K,V> pollLastEntry(): Returns and removes the last key-value pair
NavigableMap<K,V> descendingMap(): Returns a NavigableMap in reverse order
NavigableSet<K> descendingKeySet(): Returns a reverse-order key set
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive):Returns a part of the map whose keys range from fromKey to toKey.
NavigableMap<K,V> headMap(K toKey, boolean inclusive):Returns a part of the map whose keys are less than toKey.
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive):Returns a part of the map whose keys are greater than or equal to fromKey.


The example should print in console the following:
keys: [1, 2, 3, 4, 5]
Ceiling: 3
Higher: 4
Floor: 3
Lower: 2
Descending keys: [5, 4, 3, 2, 1]
Head map: {1=one, 2=two}
Tail map: {1=one, 2=two}
Poll first: 1=one
Poll last: 5=five
keys: [2, 3, 4]

You can notice how the elements in the map are printed in ascending order, but the map can also be iterated in descending order with the method descendingKeySet().
The sub maps obtained with the methods headMap(), tailMap() and others are backed maps ant hey behave just like any other backed collection this is if submap is modified then also the map is modified
and viceversa.

No comments:

Post a Comment