程式扎記: [ Data Structures with Java ] Section 19.4 : Map Collection View

標籤

2011年3月28日 星期一

[ Data Structures with Java ] Section 19.4 : Map Collection View


Preface :
A map does not have an iterator for accessing its elements. This task is left to other objects, called collection views, which are sets that support the methods in the Set interface but act on the original map as the backing collection. Let us first develop an intuitive understanding of a collection view. For example, suppose we have a collection of airports and flights departing from each airport. Each flight ins an Integer object denoting the flight number. (Check below figure)


The set of airports is a view of the collection. Think of the set as a list of elements that "look in on" the actual elements in the map collection. Set operations access and update the backing collection. For instance, calling remove() for the airport set with "LAX" as the argument removes the corresponding airport and flights from the map collection. This interaction goes the other way. Removing an airport and its flights from the map has the effect of removing the airport element from the set.
In the Map interface, the method keySet() returns a set of keys in a map. This collection view implements the Set interface :
Set keys = airports.keySet();

Note that you must use the interface name Set as the reference type for the key set collection view objects. A collection view is not an independent TreeSet or HashSet collection, but rather is an object that belongs to a class which is defined within the specific map class. The available methods for a collection view object are defined by the Set interface and reference properties and elements in the backing collection.

The Key Set Collection View :
A key set views the map and its entries in terms of the keys without regard for the value components. Below figure illustrates a key set collection view of a map whose entries are pairs. A key set has access to all of the methods in the Set interface. For instance, using a key set with the contains() method determines whether the map has a entry with the specified key. The action is the same as the map containsKey() method. Using clear() with a key set object deletes all of the entries in the map and sets its size to 0. A key set iterator scans the map by sequentially accessing the entry keys. If the backing collection is a TreeMap, the iterator scans the entries in ascending order of their keys. The iterator remove() method deletes the corresponding map entry.


A key set always maintains an up-to-date view of the map keys. The size of the key set is the current size of the map. If a map operation inserts or deletes an element, the key set view changes.
A key set reference variable must have reference type Set. This is important. The variable cannot be used with the operator new to create a collection object; rather, the variable must be initialized by the map method keySet(). It then has access to a toolbox of operations defined by the Set interface. The operations deal directly with the map and its entries!

The Entry Set Collection View :
In the Map interface, a second view, called an entry set, is the set of key-value entries which is returned by the map method entrySet(). You need some details about map notation to effectively use an entry set. Elements in a map implement the Entry interface. The identifier "Entry" is defined as an interface within the Map interface. Internally, a map class implementation declares a class that implements the Map.Entry interface. The elements in the map are instances of this class. The Map.Entry interface defines three methods getKey(), getValue() and setValue(), which access and update components in a map entry. Note that the method setKey() is not defined. It would allow a program to update the key and thus destroy the map. The method entrySet() returns a set of Map.Entry objects :

Set> entries = tm.entrySet();

An entry set views the elements in a map as a set of key-value pairs. Operations on this set affect the map in the same way that a key view can be used to modify a map. As with a key set view, this set is not an independent TreeSet or HashSet collection but is an object that belongs to a class that is defined within the specific map class. Like the key set view of a map, an entry set doest not allow the add() operation. If add() is called, the entry set throws theUnsupportedOperationException. The set can be used to define iterators that scan the elements in the map. Entry set iterators provide use the equivalent of map iterators with the ability to access an entry's key component and both access and update an entry's value component. In particular, the iterator method remove() removes an entry from the map.
- Entry Set Iterators
You can use the Set methods size(), isEmpty(), clear() and so forth with an entry set. These operations are typically handled by the corresponding map methods. The primary task of an entry set is to provide iterators that scan the elements in the map. At any point in the iteration, the iterator references a Map.Entry element in the map and the programmer can use the Map.Entry interface methods to access the components. Let use illustrate these ideas with a map that stores entries. Assume the map confTimeMap represents conference activities and their scheduled times :
  1. //Create map and add entries  
  2. TreeMap confTimeMap = new TreeMap();  
  3. confTimeMap.put("Session 1"new Time24(930));  
  4. confTimeMap.put("Session 2"new Time24(1400));  
  5. confTimeMap.put("Lunch"new Time24(120));  
  6. confTimeMap.put("Dinner"new Time24(1730));  
Creating an iterator to scan the elements in the map is a two-step process. Begin by defining an entry set for the map. Then create an iterator for the entry set :
  1. // declare an entry set for map confTimeMap  
  2. Set> entries = confTimeMap.entrySet();  
  3. // declare an iterator for the entry set using Set iterator()  
  4. Iterator> iter = entries.iterator();  
Using the iterator to access and update elements in the map involves visiting each entry as a Map.Entry object and employing the methods getValue() and setValue() to first identify the value of the entry and then to change its value. To illustrate the process, assume the conference is delayed so that all of the day's activities must be pushed forward by one half hour. After using the iterator method next() to extract an entry, addTime() increase the Time24 value component by 30 minutes :
  1. while(iter.hasNext()) {  
  2.     // extract the next element as a Map.Entry object  
  3.     Map.Entry me = iter.next();  
  4.       
  5.     // the value component (me.getValue()) is a Time24 object;  
  6.     // add 30 minutes and assign the new value to the entry  
  7.     Time24 t = me.getValue(); // Clone the element in the map.  
  8.     t.addTime(30);  
  9.     me.setValue(t);  
  10. }  
The iterator can also use the key component when scanning map elements. For instance, suppose we want to visit only the sessions and their starting time. We can use the same iteration pattern. Visit each element as a Map.Entry object and then use getKey() to access the key component which has String type. Below, we illustrate the use of foreach to implicitly iterate through the elements in the entry set :
  1. // use a foreach loop to scan the entries in the map and   
  2. // output the starting time of each conference session  
  3. for(Map.Entry i: entries) {  
  4.     String activity = i.getKey();  
  5.     if(activity.indexOf("Session")!=-1)  
  6.         System.out.println("Activity "+activity+" Starting time "+i.getValue());  
  7. }  
Output :
Activity Session 1 Starting time 10:00
Activity Session 2 Starting time 14:30
This message was edited 1 time. Last update was at 29/03/2011 09:26:34

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!