Practical Session 3 Java Collections 1 Outline Working





























- Slides: 29

Practical Session 3 Java Collections 1

Outline • Working with a Collection • The Collection interface • The Collection hierarchy • Case Study: Undoable Stack • Maps • The Collections class • Wrapper classes 2

Collection A group of elements. A collection object has many useful methods for manipulating the collection: • Insert elements • Delete elements • Clear the collection • Iterate over the elements (implements Iterable) • Investigate the collection (get. Class, size(), is. Empty(), contains(), …) • … Java’s Collections in the standard library: Vector, Array. List, Stack, Array. Dequeue, Priority. Queue, Tree. Set, Hash. Map… 3

Collection Why shouldn’t we just use arrays? Arrays have fixed size and can’t be extended Arrays are less convenient for representing certain types of collections: Sets Double-ended queues Dictionaries … Different implementations have different run-time needs Arrays are not objects! 4

Working with a collection Definition syntax: Collection-class <type> col. Name = new Collection-class <type>(…) A class that implements Collection The collection elements type Can be any class type but NOT a primitive The name of the variable Optional. Can use the Diamond <> operator instead Example: Vector <Car> cars = new Vector <Car>(); 5 Array. Queue <Job> jobs = new Array. Queue <>(10); Constructor parameters list

Working with a collection Example import java. util. Vector; … Vector <Car> cars = new Vector <>(); cars. add(new Car(“Volvo”, 2. 0)); cars. add(new Car(“BMW”, 2. 2)); Car temp = cars. element. At(0); cars. set(0, cars. element. At(1)); for (Car c: cars) 1 cars. set(1, temp); System. out. println(c); for (int i=0; i < cars. size(); i++) System. out. println(cars. element. At(i)); 26

The Collection Interface Collection is a generic interface in the standard java library. public interface Collection<E> extends Iterable<E> { int size(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); Object[] to. Array(); … 7 See Java API Docs for full definition

The Collection Hierarchy (Partial illustration) Collection List Vector Stack Set Linked. List 8 Iterable Queue Priority. Queue

The Collection Hierarchy

Case Study: Undo Various programs allow the user to undo his operations The undo operations are performed in reverse order. Implementing such a program by adding each operation into a stack 10

Case Study: Undo Action Stack Hello World 1. Type “hello world” Hello World 2. Resize 44 3. Recolor red 4. Italic on 11

Case Study: Undo UML 0. . n Undo. Stack + add (op : Operation) + undo() Operation Text. Area + undo(TA: Text. Area) -text: String -size: int Base. Operation<T> -color: int - old. Value: T - italic: boolean + Base. Operation(v. Old: T) + getters… + setters… Recolor Resize Text Italic - color: Integer - size: Integer - text: String - is. On: boolean + undo() 12

Case Study: Undo private interface Operation { public void undo(Text. Area TA); } private static abstract class Base. Operation<T> implements Operation { private T old. Value = null; public Base. Operation(T ov) {old. Value = ov; } public T get. Old. Value() { return old. Value; } } private static class Text extends Base. Operation<String> { public Text(String o. Value) { super(o. Value); } public void undo(Text. Area TA) { System. out. println("Undo Text - Set it back to text'" + get. Old. Value() + "'"); } } private static class Recolor extends Base. Operation<Integer> { public Recolor(int o. Value) { super(o. Value); } public void undo(Text. Area TA) {System. out. println("Undo Recolor - Set it back to color " + get. Old. Value()); } } private static class Resize extends Base. Operation<Integer> { public Resize(int o. Value) { super(o. Value); } public void undo(Text. Area TA) {System. out. println("Undo Resize - Set it back to size " + get. Old. Value()); } } private static class Italic extends Base. Operation<Boolean> { public Italic(Boolean o. Value) { super(o. Value); } public void undo(Text. Area TA) {System. out. println("Undo Italic - Set it back to italic " + get. Old. Value()); } }

Case Study: Undo private static class Text. Area { // WHATEVER - NOT IMPORTANT FOR THE EXAMPLE } private static class Undo. Stack { Stack<Operation> stack=new Stack<>(); Text. Area TA; public static void main(String[] args) { Text. Area TA = new public Undo. Stack(Text. Area _TA) { TA = _TA; } Undo. Stack ustack = new Undo. Stack(TA); public void add(Operation op) { stack. add(op); } public boolean undo() { if (stack. is. Empty()) return false; Operation op = stack. pop(); op. undo(TA); return true; } } 1 Text. Area(); ustack. add(new Text("")); //New value is "Hello World" ustack. add(new Resize(18)); //New value is 44 ustack. add(new Recolor(255)); //New value is red ustack. add(new Italic(false)); //New value is True while (ustack. undo()) ; } } OUTPUT: Undo Italic - Set it back to italic false Undo Recolor - Set it back to color 255 Undo Resize - Set it back to size 18 Undo Text - Set it back to text'' 2

Maps • • An object that maps keys to values. A map cannot contain duplicate keys. A map can contain duplicate values. each key can map to at most one value. 15

Maps Index 0 1 2 3 4 5 6 Value 1 0 0 6 0 9 0 Key 1 7 10 13 15 30 55 Value 6 8 4 8 8 16 46 11 : מערכים : מפות

Words count Generates a frequency table of the words found in a sentence. Example: how much wood could a woodchuck if a woodchuck could chuck wood=2, could=2, how=1, if=1, chuck=2, a=2, woodchuck=2, much=1 17

Maps Words count Example Generates a frequency table of the words found in a sentence. String sentence = "how much wood could a woodchuck if a woodchuck could chuck wood"; Q: Who’s the key and Who’s the value? Map<String, Integer> map = new Hash. Map<>(); for (String word : sentence. split(" ")) { if (map. contains. Key(word)) map. put(word, map. get(word) + 1); else map. put(word, 1); } 18

Maps Words count Example Alternative code: String sentence = "how much wood could a woodchuck if a woodchuck could chuck wood"; Map<String, Integer> map = new Hash. Map<>(); for (String word : sentence. split(" ")) { Integer freq = map. get. Or. Default(word, 0); map. put(word, freq + 1); } 19

Hash. Map vs. Tree. Map vs. Linked. Hash. Map Iteration order "how much wood could a woodchuck if a woodchuck could chuck wood"; • Hash. Map makes absolutely no guarantees about the iteration order. It can (and will) even change completely when new elements are added. • Tree. Map will iterate according to the "natural ordering" of the keys according to their compare. To() method (or an externally supplied Comparator). {a=2, chuck=2, could=2, how=1, if=1, much=1, wood=2, woodchuck=2} • Linked. Hash. Map will iterate in the order in which the entries were put into the map. {how=1, much=1, wood=2, could=2, a=2, woodchuck=2, if=1} 20

Hash. Map vs. Tree. Map vs. Linked. Hash. Map Implement of the Map interface • Hash. Map is a map based on hashing of the keys. Keys must have consistent implementations of hash. Code() and equals() for this to work. In average it takes constant time for put/get) • Tree. Map is a tree based mapping. time. It requires items to have some comparison mechanism, either with Comparable or Comparator. The iteration order is determined by this mechanism. Its put/get operations take O(log n) • Linked. Hash. Map is very similar to Hash. Map, but it adds awareness to the order at which items are added by maintains a doubly-linked list. it provides constant-time performance for the basic operations 22

Maps Hash. Map Example import java. util. Hash. Map; import java. util. Map. Entry; public class Test. Hash. Map { public class Dog { String color; Dog(String c) { //Constructor color = c; } public String to. String() { return color + " dog"; } public static void main (String[] args) { Hash. Map<Dog, Integer> hash. Map = new Hash. Map<>(); hash. Map. put(new Dog("red"), 10); hash. Map. put(new Dog("black"), 15); hash. Map. put(new Dog("white"), 20); System. out. println(hash. Map. size()); for (Entry<Dog, Integer> entry: hash. Map. entry. Set()) System. out. println(entry. get. Key() + " - " + entry. get. Value()); } } } 23 OUTPUT: 4 black dog - 15 white dog - 20 red dog - 10 white dog - 5

Maps Hash. Map Example import java. util. Hash. Map; import java. util. Map. Entry; public class Test. Hash. Map { public class Dog { String color; public static void main (String[] args) { Hash. Map<Dog, Integer> hash. Map = new Hash. Map<>(); hash. Map. put(new Dog("red"), 10); hash. Map. put(new Dog("black"), 15); hash. Map. put(new Dog("white"), 20); Dog(String c) { //Constructor System. out. println(hash. Map. size()); color = c; for (Entry<Dog, Integer> entry: hash. Map. entry. Set()) } System. out. println(entry. get. Key() + " - " public String to. String() { + entry. get. Value()); } } return color + " dog"; OUTPUT: } 3 //Override the default Object’s equals function red dog - 10 public boolean equals(Object o) { black dog - 15 return ((Dog) o). color. equals(this. color); white dog - 20 } } //What will be the output now ? 24

Maps Tree. Map Example import java. util. Map. Entry; import java. util. Tree. Map; public class Test. Tree. Map { public static void main (String[] args) { Tree. Map<Dog, Integer> tree. Map = new Tree. Map<>(); tree. Map. put(new Dog("red", 333), 10); tree. Map. put(new Dog("black", 222), 15); tree. Map. put(new Dog("white", 555), 5); tree. Map. put(new Dog("white", 444), 20); private static class Dog implements Comparable<Dog> { String color; System. out. println(tree. Map. size()); int size; for (Entry<Dog, Integer> entry: tree. Map. entry. Set()) Dog(String c, int s) { //Constructor System. out. println(entry. get. Key() + " - " + color=c; entry. get. Value()); size=s; }} OUTPUT: } 4 public String to. String() { black dog, size 222 - 15 return color + " dog, size " + size; red dog, size 333 - 10 } white dog, size 444 - 20 When using Tree. Map @Override white dog, size 555 - 5 The key object must public int compare. To(Dog other) { implement 25 return (size - other. size); Iterate elements in increasing Comparable<T> order (smallest to largest ) !!! } }

Maps Tree. Map Example import java. util. Map. Entry; import java. util. Tree. Map; public class Test. Tree. Map { private static class Dog implements Comparable<Dog> { String color; int size; Dog(String c, int s) { //Constructor color=c; size=s; } public String to. String() { return color + " dog, size " + size; } @Override public int compare. To(Dog d) { return (size - d. size); } } public static void main (String[] args) { Tree. Map<Dog, Integer> tree. Map = new Tree. Map<>(); tree. Map. put(new Dog("red", 333), 10); tree. Map. put(new Dog("black", 222), 15); tree. Map. put(new Dog("white", 222), 5); tree. Map. put(new Dog("white", 444), 20); System. out. println(tree. Map. size()); for (Entry<Dog, Integer> entry: tree. Map. entry. Set()) System. out. println(entry. get. Key() + " - " + entry. get. Value()); }} //Changed the white dog size from 555 to 222 // What will be the output now ? 26 OUTPUT: 3 black dog, size 222 - 5 red dog, size 333 - 10 white dog, size 444 - 20

The Collections class contains static methods that operate on collections: • min • max • reverse • sort • … Example: import java. util. Collections; import java. util. Vector; … Vector <Car> cars. Vec = new Vector <Car>(); … 27 Collections. reverse(cars. Vec);

Wrapper Classes What happens if we want to create a collection of a primitive type? Collections can be made only of objects. Primitive types are not objects. We use wrapper classes instead. A wrapper class is an object representing a primitive type. 28

Wrapper Classes Integer int Float float Double double Character char Boolean boolean Example: Integer int. Obj = new Integer(10); int number = int. Obj. int. Value(); 29

A collection of wrapper objects Import java. util. Vector; . . . Vector<Integer> num. Vec = new Vector <Integer>(); int size = 10; for (int i = size; i >0; i--) num. Vec. add(new Integer( i )); for (Integer i: num. Vec) System. out. println( i); Collections. sort(num. Vec); for (Integer i: num. Vec) System. out. println( i); 30