Ch 16: Data Structures - Set and Map Yonglei Tao
A set is a collection of elements Sets A set is a collection of elements Every element is unique Ordering is irrelevant Elements can be added, located, and removed Adding a duplicate of an existing element is silently ignored No way to visit elements in the order in which they are added
Set Implementation in Standard Java Library Class HashSet Uses a hash table as its data structure It arranges its elements so they can be located quickly Class TreeSet Uses a balanced binary tree as its data structure It keeps its elements in a way that makes it easy to fetch in ascending order Implementation with Linked lists - relatively slow to add, remove, and locate elements As a rule of thumb, use a hash set unless you want to visit the set elements in sorted order
Add and remove elements: Using a Set Construct the Set: Set<String> names = new HashSet<String>(); or Set<String> names = new TreeSet<String>(); Add and remove elements: names.add("Romeo"); names.remove("Juliet"); Test whether an element is contained in the set: if (names.contains("Juliet")) . . .
Visiting All Elements with an Iterator Using the “for each” loop for (String name : names){ // do something with name here } Or using an iterator Iterator<String> iter = names.iterator(); while (iter.hasNext()){ String name = iter.next(); // do something with name here } A set iterator does not visit the elements in the order in which they were added An element cannot be added to a set at an iterator position A set element can be removed at an iterator position
Sample Program - SpellCheck public class SpellCheck { public static void main(String[] args) { // Read the dictionary and the document try { Set<String> dictionaryWords = readWords(“dictionary.txt"); Set<String> documentWords = readWords(“report.txt"); } catch (IOException e) { System.out.println(“Invalid input”); } // Print all words that are in the document but not the dictionary for (String word : documentWords) { if (!dictionaryWords.contains(word)) System.out.println(word);
Sample Program – SpellCheck (Cont.) /** Reads all words from a file. @param filename the name of the file @return a set with all lowercased words in the file. Here, a word is a sequence of upper- and lowercase letters. */ public static Set<String> readWords(String filename) { Set<String> words = new HashSet<String>(); Scanner in = new Scanner(new File(filename)); // Use any characters other than a-z or A-Z as delimiters in.useDelimiter("[^a-zA-Z]+"); while (in.hasNext()) { words.add(in.next().toLowerCase()); } return words; If you changed the code to use a TreeSet instead of a HashSet. How would the output change? Answer: The words would be listed in sorted order
Sample Program – SpellCheck (Cont.) Program Run: neighbouring croqueted pennyworth dutchess comfits xii dinn clamour ... When would you choose a tree set over a hash set? Answer: When it is desirable to visit the set elements in sorted order.
Maps A map is a set of key / value pairs It is a function from one set, the key set, to another set, the value set Every key in a map has a unique value, but a value may be associated with several keys Used to find the value that is associated with a key
Map Classes and Interfaces Class HashMap Uses a hash table to minimize the search time Class TreeMap Needs extra time to insert and retrieve keys Can produce keys in sorted order To find all keys and values in a map, iterate through the key set and find the values that correspond to the keys
Example: Associate names with colors Construct the Map: Using a Map Example: Associate names with colors Construct the Map: Map<String, Color> favoriteColors = new HashMap<String, Color>(); or new TreeMap<String, Color>(); Add an association: favoriteColors.put("Juliet", Color.RED); Change an existing association: favoriteColors.put("Juliet",Color.BLUE);
Get the value associated with a key: Using a Map Get the value associated with a key: Color julietsFavoriteColor = favoriteColors.get("Juliet”); Remove a key and its associated value: favoriteColors.remove("Juliet"); Find if this map contains a mapping for a key: favoriteColors.containsKey(“Jackson"); Print key/value pairs Set<String> keySet = m.keySet(); for (String key : keySet) { Color value = m.get(key); System.out.println(key + ” : " + value); }
MapDemo.java public class MapDemo { public static void main(String[] args) { Map<String, Color> favoriteColors = new HashMap<String, Color>(); favoriteColors.put("Juliet", Color.BLUE); favoriteColors.put("Romeo", Color.GREEN); favoriteColors.put("Adam", Color.RED); favoriteColors.put("Eve", Color.BLUE); // Print all keys and values in the map Set<String> keySet = favoriteColors.keySet(); for (String key : keySet) { Color value = favoriteColors.get(key); System.out.println(key + " : " + value); }
MapDemo.java (cont.) Program Run: Romeo : java.awt.Color[r=0,g=255,b=0] Eve : java.awt.Color[r=0,g=0,b=255] Adam : java.awt.Color[r=255,g=0,b=0] Juliet : java.awt.Color[r=0,g=0,b=255] What is the difference between a set and a map? Answer: A set stores elements. A map stores associations between keys and values. Why is the collection of the keys of a map a set? Answer: The ordering does not matter, and you cannot have duplicates.