CS 340 DATA STRUCTURES Lecture: ArrayList, Iterator CS 340 1.
-
Upload
avis-oliver -
Category
Documents
-
view
237 -
download
0
Transcript of CS 340 DATA STRUCTURES Lecture: ArrayList, Iterator CS 340 1.
CS 340 1
CS 340 DATA STRUCTURESLecture: ArrayList, Iterator
CS 340 2
Containers Illustration
import java.util.*;public class PrintingContainers { static Collection fill(Collection c) { c.add(“dog”); c.add(“dog”); c.add(“cat”); return c; } static Map fill(Map m) { m.put(“dog”, “Bosco”); m.put(“dog”, “Spot”); m.put(“cat”, “Rags”); return m; } public static void main(String[] args) { System.out.println(fill(new ArrayList())); // toString() used System.out.println(fill(new HashSet())); System.out.println(fill(new HashMap())); }}
CS 340 3
Containers Illustration
• The arguments and return types of fill() are the general interface types, for generality.
• The results look like this:
• Elements of Sets and keys of Maps are unique, and ordered (here, lexicographically).
• Lists hold things in the order in which you enter them.
[dog, dog, cat][cat, dog]{cat=Rags, dog=Spot}
CS 340 4
Java Containers Hold “Objects”
• All the container classes are defined (by Sun) to hold (references to) Objects.
• So, the exact type of an object is lost.• This is far less safe than ordinary arrays, but is more
powerful.• If you know what type of thing went into the container, you
can cast it to the correct type.
CS 340 5
Eckel’s Cats’n’Dogs
public class Cat { private int catNumber; Cat(int i) { catNumber = i; } void print() { System.out.println(“Cat #” + catNumber); }}public class Dog { private int dogNumber; Dog(int i) { dogNumber = i; } void print() { System.out.println(“Dog #” + dogNumber); }}
CS 340 6
Cats’n’Dogs (cont.)
import java.util.*;
public class CatsAndDogs { public static void main(String[] args) { ArrayList cats = new ArrayList(); for (int i = 0; i < 7; i++) cats.add(new Cat(i)); // here’s trouble cats.add(new Dog(8)); for(int i = 0; i < cats.size(); i++) ( (Cat) cats.get(i) ).print(); }}
CS 340 7
Cats’n’Dogs (cont.)
• A Dog in the cats ArrayList is perfectly legal.• The compiler has no way of knowing this is wrong.• At runtime, when the Dog is cast to a Cat, trouble occurs
(giving an exception).• (Note the extra set of parentheses in the cast.)
CS 340 8
A Type-Conscious ArrayList
import java.util.*;
public class CatList { // no Dogs allowed private ArrayList list = new ArrayList(); public void add(Cat c) { list.add(c); } public Cat get(int index) { return (Cat) list.get(index); } public int size() { return list.size(); }}
CS 340 9
Iterators For Collections• The Iterator interface specifies
• boolean hasNext()• Object next()• void remove()
• You just have to be careful• to check hasNext() before using next()• to not modify the Collection while iterating, except by using
remove()
CS 340 10
Simple Iterator Example
• We get the iterator by asking the ArrayList for one.• On creation, it is positioned “just before the beginning” of
the ArrayList.
ArrayList cats = new ArrayList();for (int i = 0; i < 7; i++) cats.add(new Cat(i));Iterator e = cats.iterator();while (e.hasNext()) ( (Cat)e.next()).print();
CS 340 11
Let’s Be Clear On This!
ArrayList cats
Iterator e = cats.iterator();while (e.hasNext()) ( (Cat)e.next()).print(); When e is here,
hasNext() returnsfalse.
CS 340 12
Another Example
• There is no knowledge about the type of thing being iterated over.
• This also shows the power of the “toString() idea”.
class Printer { static void printAll(Iterator e) { while(e.hasNext()) System.out.println(e.next());}
CS 340 13
Collection Interface Methods
• boolean add(Object)• boolean addAll(Collection)• void clear()• boolean contains(Object)• boolean containsAll(Collection)• boolean isEmpty()• Iterator iterator()
“optional”
CS 340 14
Collection Interface Methods• boolean remove(Object)• boolean removeAll(Collection)• boolean retainAll(Collection)• int size()• Object[] toArray()• Object[] toArray(Object[] a)
“optional”
CS 340 15
What’s Missing?• All the methods that use indexes:
• boolean add(int, Object)• boolean addAll(int, Collection)• Object get(int)• int indexOf(Object)• Object set(int, Object)
• Why? Sets (HashSet, TreeSet) have their own way of ordering their contents. But ArrayList and LinkedList have these methods, since they are…lists.
CS 340 16
Collections Example
public class AABattery { public String toString() { return "AABattery"; }}public class NineVoltBattery { public String toString() { return "NineVoltBattery"; }}public class RollOfRibbon { public String toString() { return "RollOfRibbon"; }}public class PaperClip { int i; PaperClip(int i) { this.i = i; } public String toString() { return "PaperClip(" + i + ")"; }}
CS 340 17
Collections Example (cont.)
public class BandAid { public String toString() { return "BandAid"; }}public class Box { ArrayList moreStuff = new ArrayList(); public String toString() { String s = new String("Box");
s += moreStuff; return s; }}
CS 340 18
Collections Example (cont.)
public class BoxOfPaperClips { ArrayList clips = new ArrayList(); public String toString() { String s = new String("BoxOfPaperClips"); s += clips; return s; }}
CS 340 19
public class JunkDrawer { ArrayList contents = new ArrayList(); public void fillDrawer() { contents.add(new RollOfRibbon()); contents.add(new AABattery()); contents.add(new NineVoltBattery()); BoxOfPaperClips boxOfClips = new BoxOfPaperClips(); for (int i = 0; i < 3; i++) boxOfClips.clips.add(new PaperClip(i)); contents.add(boxOfClips); Box box = new Box(); box.moreStuff.add(new AABattery()); box.moreStuff.add(new BandAid()); contents.add(box); contents.add(new AABattery()); }
Collections Example (cont.)
CS 340 20
Collections Example (cont.)
public static void main(String[] args) { JunkDrawer kitchenDrawer = new JunkDrawer(); kitchenDrawer.fillDrawer(); System.out.println(kitchenDrawer.contents); }}
This prints
[RollOfRibbon, AABattery, NineVoltBattery, BoxOfPaperClips[PaperClip(0), PaperClip(1), PaperClip(2)], Box[AABattery, BandAid], AABattery]
CS 340 21
Removing Stuff
• This doesn’t work at all!• You need to have a reference to a battery actually in the drawer.
• How do you figure out if something is an AABattery?
void takeAnAABattery() { boolean b = contents.remove(new AABattery()); if (b) System.out.println("One AABattery removed"); }
CS 340 22
Using RTTI
boolean takeAnAABattery() { Iterator i = contents.iterator(); Object aa = null; // initialize, or compiler complains while(i.hasNext()) { if ( (aa = i.next()) instanceof AABattery ) {
contents.remove(aa); return true; } } return false; }
CS 340 23
Containers Are Good, But…• Everything in a container is “just an Object.”• If you aren’t sure what’s in there, and its location, then
finding what you want can be tedious.• Can we do better?
CS 340 24
A “More Organized” Drawer
public class MarthaStewartDrawer { ArrayList contents = new ArrayList(); ArrayList aaBatteries = new ArrayList(); public void fillDrawer() { contents.add(new RollOfRibbon()); AABattery a1 = new AABattery(); AABattery a2 = new AABattery(); contents.add(a1); aaBatteries.add(a1); //add all the rest… contents.add(a2); aaBatteries.add(a2); }
CS 340 25
Remove An Entire Collection
boolean takeAllAABatteries() { return contents.removeAll(aaBatteries); } public static void main(String[] args) { MarthaStewartDrawer kitchenDrawer = new MarthaStewartDrawer(); kitchenDrawer.fillDrawer(); System.out.println(kitchenDrawer.contents); if (kitchenDrawer.takeAllAABatteries()) System.out.println("All AABatteries removed"); System.out.println(kitchenDrawer.contents); }}
CS 340 26
Or, Remove Everything Except...
• This is actually the “set intersection” of contents with aaBatteries.
• Note, however, that this removes the AABatterys in the Box…
boolean leaveOnlyAABatteries() { return contents.retainAll(aaBatteries); }
CS 340 27
Specialized Collections• The List interface:
• Gives you the Collection interface, plus more• Insertion order is preserved• You can “index into” a List• The concrete types are ArrayList and LinkedList.
• The Set interface:• Just the Collection interface, but with specialized
behavior• Insertion order isn’t preserved.• The concrete types are HashSet and TreeSet.
CS 340 28
Lists Produce ListIterators
<<instantiate>>
<<instantiate>>
interfaceSet
interfaceSortedSet
AbstractCollection
AbstractSetAbstractList
ArrayList HashSet TreeSetAbstractSequentialList
LinkedList
interfaceIterator
interfaceListIterator
interfaceCollection
interfaceList
CS 340 29
Operational Efficiencies• ArrayList
• Holds data internally as an array (duh!)• Random access is fast, just “index into” the array• Insertion (except at the end) is very slow
• LinkedList• Random access is slow (but provided for)• Insertion anywhere is fast (once you are there!)
CS 340 30
GENERIC COLLECTIONS
CS 340 31
Generic Collections
The statement
List<String> myList = new ArrayList<String>();
uses a language feature called generic collections or generics
The statement creates a List of String; only references of type String can be stored in the list
String in this statement is called a type parameter The type parameter sets the data type of all objects
stored in a collection
CS 340 32
Generic Collections (cont.)
The general declaration for generic collection isCollectionClassName<E> variable =
new CollectionClassName<E>(); The <E> indicates a type parameter Adding a noncompatible type to a generic collection will
generate an error during compile time However, primitive types will be autoboxed:
ArrayList<Integer> myList = new ArrayList<Integer>(); myList.add(new Integer(3)); // okmyList.add(3); // also ok! 3 is automatically wrapped in an Integer objectmyList.add(new String("Hello")); // generates a type incompatability error
CS 340 33
Why Use Generic Collections?
• Better type-checking: catch more errors, catch them earlier
• Documents intent• Avoids the need to downcast from Object
CS 340 34
Slides adopted from: CS 146: Data Structures and Algorithms © R. Mak
ARRAYLIST APPLICATIONS
35
Primitive Types and Reference Types• Java has primitive types and reference types.
• Primitive types are int, short, long, byte , float, double, char, and boolean.
36
Primitive Types and Reference Types• Reference types (AKA object types) are for objects that
are created with the new operator.• Java objects are always referred to by pointers.
• Built-in reference types include Object, Integer,
Float, Date, System, ArrayList, Hashtable• Object is the root of all reference types
in the Java type hierarchy.• An array is a reference type.
• You can define custom reference types._
37
Array1: Sort an Array of Integers• Main:
• Print:
public static void main(String[] args) { int numbers[] = new int[] {5, 1, 9, 4, 5, 0, 7, 6};
System.out.print("Before sorting:"); print(numbers); sort(numbers); System.out.print(" After sorting:"); print(numbers);}
private static void print(int elements[]){ for (int elmt : elements) { System.out.print(" " + elmt); } System.out.println();}
Primitive int data.
38
Array2: Use an ArrayList• Main:
• An ArrayList can only store instances (objects) of a reference type such as Integer, not primitive type data such as int.
public static void main(String[] args) { ArrayList numbers = new ArrayList(); numbers.add(new Integer(5)); numbers.add(new Integer(1)); numbers.add(new Integer(9)); numbers.add(new Integer(4)); numbers.add(new Integer(5)); numbers.add(new Integer(0)); numbers.add(new Integer(7)); numbers.add(new Integer(6));
System.out.print("Before sorting:"); print(numbers); sort(numbers); System.out.print(" After sorting:"); print(numbers);}
Integer objects.
39
Array2: Use an ArrayList• Print:
• A “raw” ArrayList stores Object data.• Object is the base of all Java reference types.• Therefore, we must coerce each Object element to Integer with
a type cast:• Class Integer has an intValue() method:
private static void print(ArrayList elements){ for (Object elmt : elements) { System.out.print(" " + ((Integer) elmt).intValue()); } System.out.println();}
(Integer) elmt
((Integer) elmt).intValue()
40
Dangers of Using Raw ArrayList• Since a raw ArrayList holds Object data, and Object
is the root of all Java reference types, nothing prevents us from doing this:
• What happens at run time?
ArrayList numbers = new ArrayList();numbers.add(new Integer(5));numbers.add(new Integer(1));numbers.add(new Integer(9));numbers.add(new Integer(4));numbers.add(new Date());numbers.add(new Integer(0));numbers.add(new Integer(7));numbers.add(new Integer(6));
41CS 146: Data Structures and Algorithms
© R. Mak
Array3: Use ArrayList<Integer>public static void main(String[] args) { ArrayList<Integer> numbers = new ArrayList<>(); numbers.add(new Integer(5)); numbers.add(new Integer(1)); numbers.add(new Integer(9)); numbers.add(new Integer(4)); numbers.add(new Integer(5)); numbers.add(new Integer(0)); numbers.add(new Integer(7)); numbers.add(new Integer(6));
System.out.print("Before sorting:"); print(numbers); sort(numbers); System.out.print(" After sorting:"); print(numbers);}
Now the compiler will prevent us from adding anything other than Integer data to the array list.
42
Array3: Use ArrayList<Integer>private static void print(ArrayList<Integer> elements){ for (Integer elmt : elements) { System.out.print(" " + elmt.intValue()); } System.out.println();}
We no longer need to coerceelement data to Integer because that’s the only allowable data type in ArrayList<Integer>.
43
Boxing and Unboxing• Boxing
• We “wrap” an int value in an Integer object:
• Unboxing• We “unwrap” an int value from an Integer object:
• Java does autoboxing/unboxing as necessary, so we don’t have to explicitly do it in our code._
int i = int obj.intValue()
Integer obj = new Integer(3);
44
Array4: Autobox/Unbox public static void main(String[] args) { ArrayList<Integer> numbers = new ArrayList<>(); numbers.add(5); numbers.add(1); numbers.add(9); numbers.add(4); numbers.add(5); numbers.add(0); numbers.add(7); numbers.add(6);
System.out.print("Before sorting:"); print(numbers); sort(numbers); System.out.print(" After sorting:"); print(numbers);}
Java will autobox each int valueto an Integer object beforeadding it to the array list.
45
Array4: Autobox/Unboxprivate static void print(ArrayList<Integer> elements){ for (Integer elmt : elements) { System.out.print(" " + elmt); } System.out.println();}
Auto-unbox the int valuefrom an Integer object.
46
Comparisons Among Other Object Types
• If a reference class implements the Comparable interface, then you can compare instances (objects) of that class to each other.• You have to write (implement)
the interface’s compareTo() method.
• For example, we can define shape objects such as squares, rectangles, and circles and compare their areas._
47
Abstract Class SimpleShape
• Implements the Comparable interface.• It implements the interface’s compareTo() method.
• Returns a negative, zero, or positive int value if the comparison is less than, equal to, or greater than, respectively.
• Subclasses will implement method area().
public abstract class SimpleShape implements Comparable{ public abstract float area();
public int compareTo(Object other) { return (int) (this.area() - ((SimpleShape) other).area()); }} Comparable is a raw interface. Type casting needed.
48
Subclass Square• Subclass Square implements method area().
public class Square extends SimpleShape{ private float width;
public Square(float width) { this.width = width; }
public float area() { return width*width; }}
49
Subclass Rectangle• Subclass Rectangle has its implementation
of method area().
public class Rectangle extends SimpleShape { private float width, height;
public Rectangle(int width, int height) { this.width = width; this.height = height; }
public float area() { return width*height; }}
50
Subclass Circle• Subclass Circle has its implementation
of method area().
public class Circle extends SimpleShape { private static final float PI = 3.1415926f; private float radius;
public Circle(float radius) { this.radius = radius; }
public float area() { return PI*radius*radius; }}
51
Array5: SimpleShape Objectspublic static void main(String[] args) { ArrayList<SimpleShape> shapes = new ArrayList<>(); shapes.add(new Square(5)); shapes.add(new Rectangle(3, 4)); shapes.add(new Circle(2));
System.out.print("Before sorting:"); print(shapes); sort(shapes); System.out.print(" After sorting:"); print(shapes);}
52
Array5: SimpleShape Objectsprivate static void print(ArrayList<SimpleShape> elements){ for (SimpleShape elmt : elements) { System.out.print(" " + elmt); } System.out.println();}
53
Array6: Comparable<SimpleShape>• Type casting no longer needed!
public abstract class SimpleShape implements Comparable<SimpleShape>{ public abstract float area();
public int compareTo(SimpleShape other) { return (int) (this.area() - other.area()); }}
54
Arrays are Covariant• Square is a subclass of class SimpleShape, therefore Square objects are type compatible with SimpleShape objects.
• Java arrays are covariant, which means that in this case, a Square[] array is type compatible with a SimpleShape[] array._
55
Array7: Covariant Arrayspublic static void main(String[] args) { SimpleShape shapes[] = new SimpleShape[] { new Square(5), new Rectangle(3, 4), new Circle(2) };
System.out.println("Total area: " + totalArea(shapes));
Square squares[] = new Square[] { new Square(5), new Square(3), new Square(2) };
System.out.println("Total area: " + totalArea(squares));}
We can pass a Square[].
56
Array8: ArrayList Types are Not Covariant
• This will not compile.
private static float totalArea(ArrayList<SimpleShape> elements){ float total = 0;
for (SimpleShape elmt : elements) { total += elmt.area(); }
return total;}
public static void main(String[] args) { ArrayList<Square> squares = new ArrayList<>(); squares.add(new Square(5)); squares.add(new Square(3)); squares.add(new Square(2));
System.out.println("Total area: " + totalArea(squares));}
Cannot pass an ArrayList<Square>to an ArrayList<SimpleShape>.
57
Array9: Fix the Noncovariance Problemprivate static float totalArea(ArrayList<? extends SimpleShape> elements) { float total = 0;
for (SimpleShape elmt : elements) { total += elmt.area(); }
return total;}
public static void main(String[] args) { ArrayList<Square> squares = new ArrayList<>(); squares.add(new Square(5)); squares.add(new Square(3)); squares.add(new Square(2));
System.out.println("Total area: " + totalArea(squares));}
58
Arrays are not good enoughint [ ] arr = new int[ 10 ];...// Later on we decide arr needs to be larger.int [ ] newArr = new int[ arr.length * 2 ];
for( int i = 0; i < arr.length; i++ )newArr[ i ] = arr[ i ];
arr = newArr;
CS 340 59
Implementing ArrayList.add(E)(cont.)
If size is less than capacity, then to append a new item 1. insert the new item at the position indicated by the value of
size2. increment the value of size3. return true to indicate successful insertion
CS 340 60
Implementing ArrayList.add(int index,E anEntry)
To insert into the middle of the array, the values at the insertion point are shifted over to make room, beginning at the end of the array and proceeding in the indicated order
CS 340 61
remove Method
• When an item is removed, the items that follow it must be moved forward to close the gap
• Begin with the item closest to the removed element and proceed in the indicated order
CS 340 62
Collection interface
1 public interface Collection<AnyType> extends Iterable<AnyType>
2 {3 int size( );4 boolean isEmpty( );5 void clear( );6 boolean contains( AnyType x );7 boolean add( AnyType x );8 boolean remove( AnyType x );9 java.util.Iterator<AnyType> iterator( );10 }
CS 340 63
Iterator interface
1 public interface Iterator<AnyType>2 {3 boolean hasNext( );4 AnyType next( );5 void remove( );6 }
CS 340 64
Printing a collection BI (Before Iterators )
1 public static <AnyType> void print( Collection<AnyType> coll )2 {3 for( AnyType item : coll )4 System.out.println( item );5 }
CS 340 65
Printing a collection AI (After Iterators )
1 public static <AnyType> void print( Collection<AnyType> coll )2 {3 Iterator<AnyType> itr = coll.iterator( );4 while( itr.hasNext( ) )5 {6 AnyType item = itr.next( );7 System.out.println( item );8 }9 }