ADSA: Maps/9 1 241-423 Advanced Data Structures and Algorithms Objectives – –examples of maps,...

42
ADSA: Maps/9 241-423 Advanced Data Structures and Algorithms Objectives examples of maps, and introduce map collection views Semester 2, 2013-2014 9. Maps

Transcript of ADSA: Maps/9 1 241-423 Advanced Data Structures and Algorithms Objectives – –examples of maps,...

ADSA : Maps/9 1

241-423 Advanced Data Structures and Algorithms

Objectives– examples of maps, and introduce map

collection views

Semester 2, 2013-2014

9. Maps

ADSA : Maps/9 2

Contents1. What is a Map?

2. Map Interfaces

3. The TreeMap Collection

4. Map Collection Views

5. Create a Concordance

ADSA : Maps/9 3

1. What is a Map?• A map stores data in key‑value pairs.

• A key acts like an index to locate the corresponding value in the map– a map is also called an associative array

ADSA : Maps/9 4

2. The Map Hierarchy

• The dashed lines indicate that the class implements the interface.

• The Map interface is separate from the Collection hierarchy, since if defines methods not relevant to general collections.

ADSA : Maps/9 5

interface MAP<K,V> (partial) ds.util

void clear() Removes all mappings from this map.

boolean

containsKey(Object key) Returns true if this map contains a mapping for the specified key.

boolean

isEmpty() Returns true if this map contains no key-value mappings.

V remove(Object key) Removes the mapping for this key from this map if present. Returns the previous value associated with specified key, or null if there was no mapping for key.

int size() Returns the number of key-value mappings in this map.

Access/Update Methods

K get(Object key) Returns the value to which this map maps the specified key or null if the map contains no mapping for this key.

V put(K key, V value) Associates the specified value with the specified key in this map. Returns the previous value associated with key, or null if there was no mapping for key.

The Map Interface

V

K

K

K

ADSA : Maps/9 6

• size(), isEmpty(), and clear() are like those in the Collection interface.

• A map does not have an iterator to scan its elements– instead, keySet() and entrySet() return the keys

and the entries in a map as a set (see later)

ADSA : Maps/9 7

3. The TreeMap Collection

• TreeMap is an ordered collection that accesses elements in ascending order of its keys.

• The class implements the OrderedMap interface (see slide 3)– firstKey() and lastKey() return the values

corresponding to the minimum and maximum keys

ADSA : Maps/9 8

class TreeMap<K,V> implements OrderedMap<K,V> ds.util

Constructor

TreeMap() Creates an empty ordered map. The key type K must implement Comparable.

Methods

T firstKey() Returns the value associated with the entry that has the minimum key.

T lastKey() Returns the value associated with the entry that has the maximum key.

String toString() Returns a comma-separated list of entries enclosed in braces ("{}"). Each entry has the format "key = value".

V

V

ADSA : Maps/9 9

Brief TreeMap Example// arrays for class names and their enrollment (student nos)String[] className = {"ECON 101","CS 173","ENGL 25"};int[] enrollment = {85, 14, 30};

// create a TreeMap objectTreeMap<String, Integer> tm = new TreeMap<String, Integer>();for(int i = 0; i < 3; i++)

tm.put(className[i], enrollment[i]);

ADSA : Maps/9 10

3.1. Student Working Hours Mapimport java.util.Scanner;import java.io.FileReader;import java.io.FileNotFoundException;

import ds.util.TreeMap;import ds.time.Time24;

public class CalcHours{ public static void main(String[] args) { TreeMap<String, Time24> workMap = new TreeMap<String,Time24>(); :

the key-value pair is student name and hours worked

ADSA : Maps/9 11

/* access the student info file: each line consists of a student name and their work time in hours and mins */ Scanner fin = null; try { // load student info fin = new Scanner(new FileReader("studwk.txt")); } catch (FileNotFoundException e) { System.err.println("Cannot open "\"studwk.txt""); System.exit(1); } :

ADSA : Maps/9 12

// input names and times while (fin.hasNext()) { String studName = fin.next();

// get hours and minutes from the input line int hours = fin.nextInt(); int mins = fin.nextInt();

Time24 workTime = new Time24(hours,mins);

// access entry for the student name Time24 timeValue = workMap.get(studName); :

ADSA : Maps/9 13

if (timeValue == null) // add new entry workMap.put(studName, workTime); else { // update existing entry timeValue.addTime(hours*60 + mins); workMap.put(studName, timeValue); } }

// display the work Map System.out.println("Student-Time: " + workMap); } // end of main()

} // end of CalcHours class

ADSA : Maps/9 14

Execution

ADSA : Maps/9 15

3.2. A Software Mapimport java.io.FileReader;import java.io.FileNotFoundException;import java.util.Scanner;

import ds.util.TreeMap;import ds.util.TreeSet;

public class MakeSoftMap{ public static void main(String[] args) { TreeMap<String, TreeSet<String>> softwareMap = new TreeMap<String, TreeSet<String>>(); :

the key-value pair is company name and a set of software names

ADSA : Maps/9 16

/* access the product info file: each line consists of a company name and software product name, separated by a tab */ Scanner fin = null; try { // load product info fin = new Scanner(new FileReader("product.txt")); fin.useDelimiter("[\t\n\r]+"); } catch (FileNotFoundException e){ System.err.println("Cannot open "\"product.txt\""); System.exit(1); } :

ADSA : Maps/9 17

while(fin.hasNext()){ String company = fin.next(); String product = fin.next();

// look for software set for the company TreeSet<String> prodSet = softwareMap.get(company);

// if no entry found, then create empty software set if (prodSet == null) prodSet = new TreeSet<String>();

prodSet.add(product); // add product name to set softwareMap.put(company, prodSet); // add entry }

// display contents of software Map System.out.println(softwareMap); } // end of main()

} // end of MakeSoftMap class

ADSA : Maps/9 18

Execution

ADSA : Maps/9 19

4. Map Collection Views

• A map does not have an iterator for accessing its elements.

• Instead we can use two collection views, which are sets that act on the original map– the keySet collection view– the entrySet collection view

• The original map is sometimes called the backing collection.

ADSA : Maps/9 20

• In Map, keySet() returns a set of map keys. This set is a collection view for the map.

Set<String> keys = peopleMap.keySet();

4.1. The keySet Collection View

ADSA : Maps/9 21

Deletion• Deleting a key from the set removes the

corresponding entry from the map.

ADSA : Maps/9 22

• The Set interface defines an add() operation, but this makes no sense for a keySet view: – add() would have to add a key-value pair to the

backing collection, but what value should be added?

– Instead add() throws an UnsupportedOperationException in a keySet view

Insertion

ADSA : Maps/9 23

4.2. The entrySet Collection View

• In Map, entrySet() returns a view called an entry set, is a set of key-value entries.

• The entries implement the Map.Entry interface– an interface inside the Map interface

Set< Map.Entry<String, Integer> > entriesSet = peopleMap.entrySet();

ADSA : Maps/9 24

• entriesSet is a set of Map.Entry objects from the peopleMap.

• Operations on the set affect the map.

interface MAP.ENTRY<K,V> ds.util.Map

K getKey() Returns the key corresponding to this entry..

V getValue() Returns the value corresponding to this entry..

V setValue(V value) Replaces the value corresponding to this entry with the specified value. Returns the old value corresponding to the entry

ADSA : Maps/9 25

• confTimeMap holds conference activities and their times.

TreeMap<String, Time24> confTimeMap = new TreeMap<String, Time24>();

confTimeMap.put("Session 1", new Time24(9,30));confTimeMap.put("Session 2", new Time24(14,00));confTimeMap.put("Lunch", new Time24(12,0));confTimeMap.put("Dinner", new Time24(17,30));

Entry Set View Example

confTimeMap

ADSA : Maps/9 26

// create an entry set for confTimeMapSet< Map.Entry<String,Time24> > entries = confTimeMap.entrySet();

entries set

ADSA : Maps/9 27

4.3. Scanning a Map's Entries

• A Map.Entry set can be used to define an iterator for scanning the map entries.

• The iterator can access an entry's key and access/update an entry's value.

• The iterator remove() method removes an entry from the map

ADSA : Maps/9 28

Entry Set Iterators

• An entry set iterator provides a way to scan the entries in a map.

• The iterator references a Map.Entry element in the map – the programmer can use Map.Entry methods to

access the map components

ADSA : Maps/9 29

// create an entry set for confTimeMapSet< Map.Entry<String,Time24> > entries = confTimeMap.entrySet();

// create an iterator for the entry setIterator< Map.Entry<String, Time24> > iter = entries.iterator();

Examples

entries set

iteriterator

continued

ADSA : Maps/9 30

mapentries

setentriesiterator

changes will affectoriginal map

ADSA : Maps/9 31

• Delay all activities by 30 minutes.

// scan map entries while (iter.hasNext()) {

Map.Entry<String, Time24> me = iter.next(); // get next Map.Entry object

Time24 t = me.getValue();t.addTime(30); // add 30 minsme.setValue(t); // update map entry

}

ADSA : Maps/9 32

for (Map.Entry<String,Time24> i : entries) { String activity = (String)i.getKey(); if (activity.indexOf("Session") != -1) //is activity a session? System.out.println("Activity " + activity +

" Starting time " + i.getValue());}

Activity Session 1 Starting time 10:00Activity Session 2 Starting time 14:30

• List session starting time.

ADSA : Maps/9 33

5. Create a Concordance

• A concordance is a list of all the unique words from a file along with the line numbers where the words appear.

• We implement the concordance as a TreeMap.

ADSA : Maps/9 34

Input File

ADSA : Maps/9 35

Execution

ADSA : Maps/9 36

import java.io.*;import java.util.regex.*;import java.util.StringTokenizer;import java.util.Scanner;import ds.util.*;

public class CreateConcordance{ private static Pattern identifierPattern = Pattern.compile("[a-zA-Z][a-zA-Z0-9]*");

public static void main(String[] args) throws IOException { System.out.print("Enter the file name: "); Scanner keyIn = new Scanner(System.in); String filename = keyIn.nextLine(); System.out.println(); concordance(filename); // create concordance } // end of main()

ADSA : Maps/9 37

public static void concordance(String filename) throws IOException {

// create the concordance treemap TreeMap<String, TreeSet<Integer>> concordanceMap = new TreeMap<String, TreeSet<Integer>>();

// create scanner to input from document file Scanner fin = new Scanner(new FileReader(filename)); :

the key-value pair is identifier name and a set of line numbers

ADSA : Maps/9 38

// read the file a line at a time int lineNumber = 0; while(fin.hasNext()) { String inputLine = fin.nextLine(); // read a line lineNumber++;

// create matcher to find identifiers in line Matcher matcher = identifierPattern.matcher(inputLine);

// extract identifiers until end of line while (matcher.find()) { String ident = inputLine.substring( matcher.start(), matcher.end()); :

ADSA : Maps/9 39

// find line number set for the identifier TreeSet<Integer> lineNums = concordanceMap.get(ident);

if (lineNums == null) // no set; make one lineNums = new TreeSet<Integer>();

// add line number to set lineNums.add(lineNumber); concordanceMap.put(ident, lineNums); } }

// output the concordance writeConcordance(concordanceMap);

} // end of concordance()

ADSA : Maps/9 40

public static void writeConcordance( TreeMap<String,TreeSet<Integer>> map) { // create entry view for the map Set<Map.Entry<String,TreeSet<Integer>>> entries = map.entrySet(); // create iterator over the entry view Iterator<Map.Entry<String,TreeSet<Integer>>> iter = entries.iterator();

while (iter.hasNext()) { Map.Entry<String,TreeSet<Integer>> e = iter.next(); System.out.print( e.getKey() ); // output key

// pad output to 12 characters using blanks if (e.getKey().length() < 12) for (int i=0;i < 12 - (e.getKey().length()); i++) System.out.print(' '); :

ADSA : Maps/9 41

// extract map value as a TreeSet TreeSet<Integer> lineNumberSet = e.getValue();

// display identifier and line numbers System.out.print(formatInt(4, lineNumberSet.size()) + ": ");

// iterate over TreeSet of line numbers Iterator<Integer> setIter = lineNumberSet.iterator(); while (setIter.hasNext()) System.out.print( setIter.next() + " "); System.out.println(); } System.out.println(); }

ADSA : Maps/9 42

private static String formatInt(int w, int n) /* returns a formatted string with integer n right-justified in a field of w spaces; used to line up output in concordance */ { . . . }

} // end of CreateConcordance class