Lecture 07 Collections PDF
Document Details
Uploaded by MagicalAmaranth
Lebanese University
Omar Rifi
Tags
Summary
This lecture covers Java Collections Framework, focusing on Lists, Sets, Maps, and Iterators. It includes examples using ArrayList and explains important concepts about object types. The presenter is Omar Rifi from Lebanese University.
Full Transcript
Lecture 07 Collections Lists, Sets, Maps & Iterators Omar Rifi Lebanese University Faculty of Sciences III Omar Rifi (LU-FS3)...
Lecture 07 Collections Lists, Sets, Maps & Iterators Omar Rifi Lebanese University Faculty of Sciences III Omar Rifi (LU-FS3) Lecture 07Collections 1 / 26 Lists Omar Rifi (LU-FS3) Lecture 07Collections 2 / 26 The ArrayList Class (1) Consider the following code from a main method: // A dynamic list structure. ArrayList ls = new ArrayList(); // Adds an object to the end of the list (the strings hello, bye), returns true if the list has changed (it always returns true). ls.add("hello"); ls.add("bye"); // Displays the list elements (using their toString methods) System.out.println(ls); // Returns the number of objects in the list (here 2). ls.size(); Output: [hello, bye] Omar Rifi (LU-FS3) Lecture 07Collections 3 / 26 The ArrayList Class (2) // Returns true if the list is empty (here false). ls.isEmpty(); // Returns true (uses equals method) if the list contains the object (here true). ls.contains("bye"); // Inserts the object (parameter 2) at position (parameter 1) in the list and shifts elements to the right (void) ls.add(1, "hat"); System.out.println(ls); // Sets the element at position (parameter 1) to object in (parameter 2). Returns the object that has been replaced. ls.set(1, "red hat"); System.out.println(ls); Output: [hello, hat, bye] [hello, red hat, bye] Omar Rifi (LU-FS3) Lecture 07Collections 4 / 26 The ArrayList Class (3) // Returns the object at position given in parameter (as Object) ls.get(1); Object obj = ls.get(1); // or String str = (String) ls.get(1); // Downcast to String // Removes the object in parameter from the list and shifts elts to the left. Returns true if the list has changed (object is found and removed) otherwise false (object is not in the list). ls.remove("red hat"); System.out.println(ls); // Removes the object at the given position and shifts other elts to the left. Returns the object that has been removed. ls.remove(0); System.out.println(ls); Output: [hello, bye] [bye] Omar Rifi (LU-FS3) Lecture 07Collections 5 / 26 Raw Type vs Parameterized Type (1) Traversal of an ArrayList using for for (int i = 0; i < ls.size(); i++) { String str = (String) ls.get(i); //do something on str } But to that ArrayList , we are allowed to add any type of object. ls.add(new Point(1, 1)); ls.add(new Rational(1, 2)); So when dealing with such ArrayList , the developer should ensure that objects added are all of the same type in order to make the correct cast, otherwise ClassCastException may be thrown. Omar Rifi (LU-FS3) Lecture 07Collections 6 / 26 Raw Type vs Parameterized Type (2) In fact, the ArrayList class is generic ( ArrayList ), that is, we can create a Parameterized Type (using the diamond ): ArrayList ls = new ArrayList(); //or ArrayList ls = new ArrayList(); //type is inferred, or ArrayList ls = new ArrayList(); versus a Raw Type ArrayList ls = new ArrayList(); Example ArrayList ls = new ArrayList(); ls.add("hello"); ls.add(new Point(1, 1)); // Compile error String str = ls.get(0); // no more downcast needed Omar Rifi (LU-FS3) Lecture 07Collections 7 / 26 Generic, Simple Example Class Box Generic Class Box public class Box { public class Box { private Object obj; private T obj; public Object get() { public T get() { return obj; return obj; } } public void set(Object obj) { public void set(T obj) { this.obj = obj; this.obj = obj; } } } } Box could now be used to define Raw Type variables or Parameterized Type. Omar Rifi (LU-FS3) Lecture 07Collections 8 / 26 Java Collections Framework (Interfaces) ArrayList is a class among many other classes, abstract classes and interfaces that define the Java Collections Framework. Collection the main interface that defines methods common to all other interfaces and classes (add, contains, remove, iterator1 ,... ). Bulk operations2 (addAll, removeAll, retainAll, clear,... ). List that extends Collection, defines new methods to manipulate ordered list of elements (get, set, add at a given position, indexOf, subList,... ). Set that extends Collection, adds no methods, represents the concept of sets (order of elements is not important, duplication of elements is not allowed). 1 We shall introduce it later. 2 These operations are implemented in abstract classes using other basic operations. Omar Rifi (LU-FS3) Lecture 07Collections 9 / 26 Java Collections Framework (Concrete Classes) Concrete Classes ArrayList implements List (based on arrays). LinkedList implements List (based on linked nodes). HashSet implements Set (based on hash tables). TreeSet implements SortedSet which in turn extends Set (based on trees, parameterized type should be comparable). Others... Note: always use interfaces as type for variables, so you can swap between implementation. List ls = new LinkedList(); // new ArrayList(); Omar Rifi (LU-FS3) Lecture 07Collections 10 / 26 Collections Hierarchy Omar Rifi (LU-FS3) Lecture 07Collections 11 / 26 Iterator (1) While concrete classes implementing List could be traversed using a for-loop (random access), classes implementing Set could not. In order to iterate over any collection (to access elements of that collection), the framework provides all concrete classes with an iterator() method that returns an object of unknown class implementing the interface Iterator public interface Iterator { // Returns true, if there is a next element public boolean hasNext(); // Returns the next element public T next(); //Removes the element that has already been accessed. Could be called one time after a call to next() public void remove(); } Omar Rifi (LU-FS3) Lecture 07Collections 12 / 26 Iterator (2) A simple traversal Collection col = new ArrayList(); // new HashSet();... //... Iterator it = col.iterator(); while(it.hasNext()){ String str = it.next(); //do something on str } Traversal with filtering Collection col = new ArrayList(); // new HashSet();... //... Iterator it = col.iterator(); while(it.hasNext()){ String str = it.next(); if(cond(str)){ // str verifies a certain condition it.remove(); } } Omar Rifi (LU-FS3) Lecture 07Collections 13 / 26 Foreach Used when no need to access elements’ indices Collection col = new ArrayList(); // new HashSet();... //... // for each String str in col for(String str: col) { // do something on str } The foreach instruction could even be used on arrays. In fact, it could be used on any collection that implements the interface Iterable. ( Collection extends Iterable ) public interface Iterable { Iterator iterator(); } Omar Rifi (LU-FS3) Lecture 07Collections 14 / 26 Wrapper classes How to use primitive data types (int, float, double, char,...) in Collections? There is a Wrapper class for each primitive type (Integer for int, Double for double, Character for char,... containing many useful static methods). Integer g = new Integer(10); // Boxing 10 into an object int i = g.intValue(); // Unboxing the object Autoboxing allows automatic conversion between the Wrapper class and the primitive type. Integer g = 10; int i = g; In order to use primitive types in Collections, we use their corresponding wrappers. List ls = new LinkedList(); ls.add(10); int i = ls.get(0); Omar Rifi (LU-FS3) Lecture 07Collections 15 / 26 Sets Omar Rifi (LU-FS3) Lecture 07Collections 16 / 26 Review of Hashing (1) Adding elements to an array using a hash function to compute the corresponding index. In case of integers, the hash function is the identity function. Let’s add the numbers 56, 22, 37, 66 to that array of 0 22 size 11. 1 56 index(56) = hash(56)%11 = 56%11 = 1 2 index(22) = hash(22)%11 = 22%11 = 0 3 index(37) = hash(37)%11 = 37%11 = 4 4 37 5 index(66) = hash(66)%11 = 66%11 = 0, Collision! 6 Several strategies to resolve collisions. Use 7 hashi (n) = n + i2 , for i = 0, 1, 2... 8 9 10 Omar Rifi (LU-FS3) Lecture 07Collections 17 / 26 Review of Hashing (2) index(66) = hash1 (66)%11 = (66 + 1)%11 = 1 0 22 index(66) = hash2 (66)%11 = (66 + 4)%11 = 4 1 56 index(66) = hash3 (66)%11 = (66 + 9)%11 = 9 2 Simple Java code 3 4 37 //The method hashCode defined in class Object int hashcode = obj.hashCode(); 5 int index = hashcode % tab.length; 6 int i = 1; while (tab[index] != null) { 7 index = (hashcode + i * i) % tab.length; 8 i++; } 9 66 tab[index] = obj; 10 Hashing provides a more reliable and flexible method of data retrieval than any other data structure. It is faster than searching arrays and lists. Omar Rifi (LU-FS3) Lecture 07Collections 18 / 26 Review of Hashing (3) Main strategies to resolve collisions Open addressing: Linear Probing: hashi (n) = n + i, for i = 0, 1, 2... Quadratic Probing: hashi (n) = n + i2 , for i = 0, 1, 2... Double Hashing:... Separate Chaining: array slots contains lists, When two elements hashes to the same slot, they are added to the list referred from that slot. HashSet is implemented using Separate Chaining. Omar Rifi (LU-FS3) Lecture 07Collections 19 / 26 Review of Hashing (4) Now, how objects other than integer would hash? Hash functions should be implemented so that two different objects (! equals) hash to two different values. Class String, offers an implementation of hashCode() that maps the sequence characters to an integer using base 31. For a string of length n, hashcode = c0 × 31n−1 +... + cn−2 × 31 + cn−1 , where ci is the ith character in the string. For objects other than String, we may use a unique String representation of that object and return the corresponding hashCode(). IDEs would suggest to generate an implementation of hashCode(). Omar Rifi (LU-FS3) Lecture 07Collections 20 / 26 The HashSet Class Iterator on HashSet would eventually return elements in different order than the one used when those elements were added. HashSet does not allow duplicate. Two objects are duplicate if they are equals and have same hash-code. Omar Rifi (LU-FS3) Lecture 07Collections 21 / 26 The TreeSet Class TreeSet is implemented using a tree structure (Binary Search Tree). So elements used in TreeSet should have a total order (the class of these elements should implement the interface Comparable ). Iterator on TreeSet would return elements in increasing order (inorder traversal). TreeSet implements the SortedSet interface which offers more methods than the interface Collection ( first() , the lowest, last() , the largest,...) Omar Rifi (LU-FS3) Lecture 07Collections 22 / 26 Maps Omar Rifi (LU-FS3) Lecture 07Collections 23 / 26 Maps Hierarchy Omar Rifi (LU-FS3) Lecture 07Collections 24 / 26 Mapping (1) A map stores data in an associative manner (Key & Value pairs) Map map = new HashMap(); //Internally, it uses an array of Map.Entry. Method put, creates an Entry object having two attributes (key=1, value="one"), hash the value 1 to find a slot in the array and assigns the Entry to that slot. map.put(1, "one"); map.put(2, "Two"); map.put(3, "Three"); map.put(4, "Four"); System.out.println(map); if(map.containsKey(2)){ map.get(2); // returns "two"; } map.remove(4); Output: {1=one, 2=Two, 3=Three, 4=Four} Omar Rifi (LU-FS3) Lecture 07Collections 25 / 26 Mapping (2) Traversal of Maps // Returns a HashSet containing all keys Set set = map.keySet(); for(Integer i: set) { map.get(i); } System.out.println(set); // Returns a Collection containing all values Collection coll = map.values(); System.out.println(coll); Set eset = map.entrySet(); for(Map.Entry entry: eset){ int key = entry.getKey(); String value = entry.getValue(); } Output: [1, 2, 3] [one, Two, Three] Omar Rifi (LU-FS3) Lecture 07Collections 26 / 26