610 likes | 755 Views
CS203 Lecture 5. John Hurley Cal State LA. Iterators. An iterator is an object that provides methods for traversing (going through) the elements of a collection. Even with Lists, which are not hard to manipulate using loops, iterators provide easier ways to traverse data structures
E N D
CS203 Lecture 5 John Hurley Cal State LA
Iterators An iterator is an object that provides methods for traversing (going through) the elements of a collection. Even with Lists, which are not hard to manipulate using loops, iterators provide easier ways to traverse data structures In many cases, the enhanced for loop is just as convenient as an iterator.
Iterator public static void main(String[] args) { List<String> names = new LinkedList<String>(); names.add("John"); names.add("Paul"); names.add("George"); names.add("Ringo"); String currName; ListIterator<String> namesIterator = names.listIterator(); while(namesIterator.hasNext()){ currName = namesIterator.next(); System.out.println(currName + " " + (currName.compareTo("Mick") < 0? "earlier than Mick": "not earlier than Mick")); } }
Queues and Priority Queues A queue is a first-in/first-out data structure. Elements are appended to the end of the queue • In a standard queue, elements are removed from the beginning of the queue. • In a priority queue, elements are assigned priorities. When accessing elements, the element with the highest priority is removed first.
Using LinkedList for Queue LinkedList implements the Queue interface, so you can use the queue methods with an LL
Using LinkedList for Queue public static void main(String[] args) throws InterruptedException { int time = 30; Queue<Integer> queue = new LinkedList<Integer>(); for (inti = time; i >= 0; i--) queue.add(i); while (!queue.isEmpty()) { System.out.println(queue.remove()); Thread.sleep(500); } }
Using LinkedList for Queue Suppose eight children will take turns on two swings. At each round, the next child in the queue gets swing # (round % 2). public static void main(String[] args) throws InterruptedException { int[] swings = {1,2}; Queue<String> queue = new LinkedList<String>(); queue.offer("Brian"); queue.offer("Diana"); queue.offer("Al"); queue.offer("Mary"); queue.offer("Mike"); queue.offer("Florence"); queue.offer("Carl"); queue.offer("Dennis"); intround = 0; while (!queue.isEmpty()) { System.out.println(queue.remove() + " uses swing # " + round % swings.length); Thread.sleep(1000); round++; } }
The PriorityQueue Class PriorityQueueDemo Run
PriorityQueue A PriorityQueue removes items in sorted order from lowest to highest value, following a convention that the item with the most important priority gets the lowest value, as in "First in Command, Second in Command," etc. Change the Queue in the swingset example to a PriorityQueue; the children will take turns in alphabetical order To control the priority order, use a PriorityQueue with objects of a class in which compareTo() is implemented to sort in the order you need, or use a Comparator Run the sample code that follows, then comment out the line that creates the PriorityQueue and uncomment the two following lines that create a Comparator and a PriorityQueue using it. Compare the output.
Comparator The Comparator interface specifies method compare(obj1, obj2). In other words, instead of comparing this object to another one as Comparable does, it compares two objects. Here are two common scenarios for Comparator: • Suppose we have a set of objects of a class that we didn't write and can’t change. It may implement Comparable, but we want to sort using a different order than the one that will be produced by Comparable. • We need to be able to compare two objects of different classes
Priority Queue package priorityqueue; public class Product implements Comparable <Product>{ String name; double priceInDollars; public String getName() { return name; } public double getPriceInDollars() { return priceInDollars; } public Product(String nameIn, double priceInDollarsIn) { name = nameIn; priceInDollars = priceInDollarsIn; } public String toString(){ return name + ": $ " + priceInDollars; } @Override public intcompareTo(Product otherProduct){ return name.compareTo(otherProduct.getName()); } }
Priority Queue package priorityqueue; import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; public class PriorityQueueDemo { public static void main(String[] args) throws InterruptedException { Queue<Product> queue = new PriorityQueue<Product>(); // Comparator<Product> comp = new ProductComparatorUsingPrice(); // Queue<Product> queue = new PriorityQueue<Product>(5, comp); queue.offer(new Product("Socks", 7.99)); queue.offer(new Product("Shoes", 59.99)); queue.offer(new Product("Laces", 1.99)); queue.offer(new Product("Hat", 23.99)); queue.offer(new Product("Shirt", 41.99)); while (!queue.isEmpty()) { System.out.println(queue.remove()); } } }
Priority Queue package priorityqueue; import java.util.Comparator; public class ProductComparatorUsingPrice implements Comparator<Product>{ @Override public int compare(Product p1, Product p2) { double diff = p1.getPriceInDollars() - p2.getPriceInDollars(); if(diff > 0) return -1; else if (diff < 0) return 1; else return 0; } }
The Stack Class The Stack class represents a last-in-first-out stack of objects. The elements are accessed only from the top of the stack. You can retrieve, insert, or remove an element from the top of the stack.
Stacks Stack<String> myStack = new Stack<String>(); myStack.push("Mary"); myStack.push("Bob"); myStack.push("Jack"); System.out.println(myStack.peek()); System.out.println(myStack.pop()); System.out.println(myStack.pop()); myStack.push("Sue"); myStack.push("Bill"); do { System.out.println(myStack.pop()); } while (!myStack.isEmpty());
Sets A Set differs from a List in these ways: • a Set does not have any inherent order • a Set may not contain any duplicate elements • This means that a set may not contain any two elements e1 and e2 such that e1.equals(e2) There are several types of Set in the Java Collections Framework. The most important ones are Hash Set and TreeSet
The Collection interface is the root interface for manipulating a collection of objects.
Hashing An object may contain an arbitrary amount of data, and searching a data structure that contains many large objects is expensive • suppose your collection of Strings stores the text of various books, you are adding a book, and you need to make sure you are preserving the Set definition – ie that no book already in the Set has the same text as the one you are adding. A hash function maps each datum to a value to a fixed and manageable size. This reduces the search space and makes searching less expensive Hash functions must be deterministic, since when we search for an item we will search for its hashed value. If an identical item is in the list, it must have received the same hash value
Hashing Any function that maps larger data to smaller ones may map more than one datum to the same value Diagram from Wikipedia When more than one item in a collection receives the same hash value, a collision is said to occur. There are various ways to deal with this. The simplest is to create a list of all items with the same hash code, and do a sequential or binary search of the list if necessary
Hashing Hash functions often use the data to calculate some numeric value, then perform a modulo operation. • This results in a bounded-length hash value. If the calculation ends in % n, the maximum hash value is n-1, no matter how large the original data is. • It also tends to produce hash values that are relatively uniformly distributed, minimizing collisions. • Modulo may be used again within a hash-based data structure in order to scale the hash values to the number of keys found in the structure
Hashing The more sparse the data, the better hashing works Sparse:A AA AB AC AD AE AF AG AH AI AJ AK AL AM AN AO AP AQ AR AS AT AU AV AW AX AY AZ Not Sparse: Juror 1 Juror 2 Juror 3 Juror 4
Hashing Hashing is used for many purposes in programming. The one we are interested in right now is that they make it easy to look up data or memory addresses in a table
The AbstractSet Class The AbstractSet class is a convenience class that extends AbstractCollection and implements Set. The AbstractSet class provides concrete implementations for the equals method and the hashCode method. The hash code of a set is the sum of the hash codes of all the elements in the set. Since the size method and iterator method are not implemented in the AbstractSet class, AbstractSet is an abstract class.
The HashSet Class The HashSet class is a concrete class that implements Set. Objects added to a hash set need to implement the hashCode() method
Duplicates Attempts to add duplicate records to a set are ignored: package demos; import java.util.HashSet; import java.util.Set; public class Demo { public static void main(String[] args) { Set<String> nameSet = new HashSet<String>(); nameSet.add("Brutus"); nameSet.add("Cicero"); nameSet.add("Spartacus"); printAll(nameSet); nameSet.add("Spartacus"); printAll(nameSet); nameSet.add("Spartacus"); printAll(nameSet); } public static <T> void printAll(Set<T> set){ System.out.println(" set contains these records: "); for(T t: set){ System.out.println(t); } } }
Hash Set Demo package demos; import java.util.HashSet; import java.util.Iterator; public class HashSetDemo { // heavily adapted from http://www-inst.eecs.berkeley.edu/~cs61c/sp13/labs/06/ // public static void main(String args[]) { String input = "The right of the people to be secure in their persons, houses, papers, and " +" effects, against unreasonable searches and seizures, shall not be violated, and no " + "Warrants shall issue, but upon probable cause, supported by Oath or affirmation, and " + "particularly describing the place to be searched, and the persons or things to be seized."; Set<String> stringSet = new HashSet<String>(); String[] words = input.split("\\W+"); // \\W+ means "one or more characters that are not alphanumeric or underscores" System.out.println("Number of words in the input is " + words.length); for (String s: words) { stringSet.add(s.toLowerCase()); } System.out.println("The number of unique words in the input is " + stringSet.size()); Iterator<String> myIterator = stringSet.iterator(); while (myIterator.hasNext()) { System.out.println(myIterator.next()); } } }
LinkedHashSet Note that the words in the output from the last example are not in the same order as they appeared in the original input. LinkedHashSet preserves the input order by using a linked list to implement a HashSet Change the HashSet in the example to LinkedHashSet and compare the output.
SortedSet Interface and TreeSet Class • SortedSet is a subinterface of Set, which guarantees that the elements in the set are sorted. • TreeSet is a concrete class that implements the SortedSet interface. • You can use an iterator to traverse the elements in the sorted order. The elements can be sorted in two ways. • One way is to use the Comparable interface. • The other is to specify a comparator for the elements in the set This approach is referred to as order by comparator • To see a TreeSet in action, return to the last demo and replace the HashSet with a TreeSet. • We will discuss the implementation of trees next week.
SortedSet Interface and TreeSet Class • To order by Comparator, write a class that implements Comparator and pass it to the TreeSet constructor • Be careful: ordering by comparator results in only one entry per group of inputs that are equal according to the compare() method in the Comparator
SortedSet Interface and TreeSet Class package demos; import java.util.Comparator; public class StringSortByLength implements Comparator <String>{ @Override public int compare(String s1, String s2) { return s1.length() - s2.length(); } }
SortedSet Interface and TreeSet Class package demos; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class TreeSetDemo { // heavily adapted from http://www-inst.eecs.berkeley.edu/~cs61c/sp13/labs/06/ // public static void main(String args[]) { String input = "The right of the people to be secure in their persons, houses, papers, " +"and effects, against unreasonable searches and seizures, shall not be " +"violated, and no Warrants shall issue, but upon probable cause, supported " +"by Oath or affirmation, and particularly describing the place to be " +"searched, and the persons or things to be seized."; Set<String> stringSet = new TreeSet<String>(new StringSortByLength()); String[] words = input.split("\\W+"); // \\W means "any character that is not alphanumeric or an underscore System.out.println("Number of words in the input is " + words.length); for (String s: words) { stringSet.add(s.toLowerCase()); } System.out.println("The number of distinct word lengths in the input is " + stringSet.size()); Iterator<String> myIterator = stringSet.iterator(); while (myIterator.hasNext()) { String nextString = myIterator.next(); System.out.println(nextString.length() + ": First example added: " + nextString); } } }
Comparator package booksdemo; public class Book implements Comparable<Book>{ String author; String title; String isbn; public Book(String author, String title, String isbn) { super(); this.author = author; this.title = title; this.isbn = isbn; } public String getAuthor() { return author; } public String getTitle() { return title; } public String getIsbn() { return isbn; } @Override public intcompareTo(Book otherBook) { intauthDiff = author.compareTo(otherBook.getAuthor()); if(authDiff != 0) return authDiff; else return title.compareTo(otherBook.getTitle()); } public String toString(){ return "Author: " + author + " Title: " + title + " ISBN: " + isbn; } }
Comparator package booksdemo; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.TreeSet; public class BookTreeSetDemo<T> { TreeSet<Book> theSet; public BookTreeSetDemo(){ theSet = new TreeSet<Book>(); } public BookTreeSetDemo(Comparator<Book> comp){ theSet = new TreeSet<Book>(comp); } public void addAll(Collection <Book> c){ theSet.addAll(c); } public void printAll(){ System.out.println("The number of items in the set is " + theSet.size()); Iterator<Book> myIterator = theSet.iterator(); while (myIterator.hasNext()) { System.out.println(myIterator.next().toString()); } }
Comparator public static void main(String[] args){ Book b1 = new Book("Smith", "Basketweaving 101", "1234-5678-9012"); Book b2 = new Book("Smith", "Basketweaving 101", "2345-6789-0123"); Book b3 = new Book("Smith", "Basketweaving 101", "2345-6789-0123"); Book b4 = new Book("Jones", "Basketweaving 102", "3456-7890-1234"); List<Book> l = new LinkedList<Book>(); l.add(b1); l.add(b2); l.add(b3); l.add(b4); BookTreeSetDemo c1 = new BookTreeSetDemo(); c1.addAll(l); c1.printAll(); Comparator<Book> comp = new BookISBNComparator(); BookTreeSetDemo c2 = new BookTreeSetDemo(comp); c2.addAll(l); c2.printAll(); } }
Maps A List or array can be thought of as a set of key-value pairs in which the keys are integers (the indexes) and the values are the data being stored. Suppose we want to be able to look up values using a key other than in integer index. For example, we need to look up friends' addresses based on their names. We could write a class with instance variables for name and address and then construct a List or Set. When we need to look up an address, we iterate through the list looking for a match for the name of the person whose address we want to look up. Maps provide a simpler alternative by mapping keys of any type to values of any other type.
The Map Interface The Map interface maps keys to the elements. The keys are like indexes. In List, the indexes are integer. In Map, the keys can be any objects.
Map Interface and Class Hierarchy An instance of Map represents a group of objects, each of which is associated with a key. You can get the object from a map using a key, and you have to use a key to put the object into the map.
HashMap and TreeMap The HashMap and TreeMap classes are two concrete implementations of the Map interface. • HashMap is efficient for locating a value, inserting a mapping, and deleting a mapping. • TreeMap, which implements SortedMap, is efficient for traversing the keys in a sorted order.
HashMap Map<String, String> myDict = new HashMap<String, String>(); myDict.put("evacuate", "remove to a safe place"); myDict.put("descend", "move or fall downwards"); myDict.put("hypochondriac", "a person who is abnormally anxious about their health"); myDict.put("injunction", "an authoritative warning or order"); myDict.put("creek", "a stream, brook, or a minor tributary of a river"); myDict.put("googol", "10e100"); String defString = "The definition of "; System.out.println(defString+ "descend : " + myDict.get("descend")); System.out.println(defString+ "injunction : " + myDict.get("injunction")); System.out.println(defString+ "googol : " + myDict.get("googol")); // http://www-inst.eecs.berkeley.edu/~cs61c/sp13/labs/06/
LinkedHashMap • The entries in a HashMap are not ordered. • LinkedHashMap extends HashMap with a linked list implementation that supports an ordering of the entries in the map. Entries in a LinkedHashMap can be retrieved in the order in which they were inserted into the map (known as the insertion order), or the order in which they were last accessed, from least recently accessed to most recently (access order). The no-arg constructor constructs a LinkedHashMap with the insertion order. • LinkedHashMap(initialCapacity, loadFactor, true).
Example: LinkedHashMap // adapted from http://www.tutorialspoint.com/java/java_linkedhashmap_class.htm public static void main(String args[]) { // Create a hash map LinkedHashMap<String, Double> lhm = new LinkedHashMap<String, Double>(); // Put elements to the map lhm.put("Zara", new Double(3434.34)); lhm.put("Mahnaz", new Double(123.22)); lhm.put("Ayan", new Double(1378.00)); lhm.put("Daisy", new Double(99.22)); lhm.put("Qadir", new Double(-19.08)); // Get a set of the entries Set<Entry<String, Double>> set = lhm.entrySet(); // Get an iterator Iterator<Entry<String, Double>> i = set.iterator(); // Display elements while (i.hasNext()) { Entry<String, Double> me = i.next(); System.out.print(me.getKey() + ": "); System.out.println(me.getValue()); } System.out.println(); // Deposit 1000 into Zara's account double balance = lhm.get("Zara").doubleValue(); lhm.put("Zara", new Double(balance + 1000)); System.out.println("Zara's new balance: " + lhm.get("Zara")); }
TreeMap package demos; import java.util.TreeMap; public class Demo { //adapted from http://www.roseindia.net/java/jdk6/TreeMapExample.shtml public static void main(String[] args) { TreeMap<Integer, String> tMap = new TreeMap<Integer, String>(); // inserting data in alphabetical order by entry value tMap.put(6, "Friday"); tMap.put(2, "Monday"); tMap.put(7, "Saturday"); tMap.put(1, "Sunday"); tMap.put(5, "Thursday"); tMap.put(3, "Tuesday"); tMap.put(4, "Wednesday"); // data ends up sorted by key value System.out.println("Keys of tree map: " + tMap.keySet()); System.out.println("Values of tree map: " + tMap.values()); System.out.println("Key: 5 value: " + tMap.get(5) + "\n"); System.out.println("First key: " + tMap.firstKey() + " Value: " + tMap.get(tMap.firstKey()) + "\n"); System.out.println("Last key: " + tMap.lastKey() + " Value: " + tMap.get(tMap.lastKey()) + "\n");
TreeMap System.out.println("All values with an enhanced for loop: "); for(String s: tMap.values()) System.out.println(s); System.out.println("First three values: "); for(String s: tMap.headMap(4).values()) System.out.println(s); System.out.println("Values starting with fourth value: "); for(String s: tMap.tailMap(4).values()) System.out.println(s); System.out.println("Removing first datum: " + tMap.remove(tMap.firstKey())); System.out.println("Now the tree map Keys: " + tMap.keySet()); System.out.println("Now the tree map contain: " + tMap.values() + "\n"); System.out.println("Removing last entry: " + tMap.remove(tMap.lastKey())); System.out.println("Now the tree map Keys: " + tMap.keySet()); System.out.println("Now the tree map contain: " + tMap.values()); } }
Case Study: Counting the Occurrences of Words in a Text This program counts the occurrences of words in a text and displays the words and their occurrences in ascending order of the words. The program uses a hash map to store a pair consisting of a word and its count. Algorithm for handling input: For each word in the input file Remove non-letters (such as punctuation marks) from the word. If the word is already present in the frequencies map Increment the frequency. Else Set the frequency to 1 To sort the map, convert it to a tree map.