28
11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality Set functionality Map functionality

11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Embed Size (px)

Citation preview

Page 1: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

11: Holding Your Objects • Introduction to containers• Container disadvantage: unknown type• Iterators• Container taxonomy• Collection functionality• List functionality• Set functionality• Map functionality

Page 2: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Introduction to containers• Container classes are one of the most powerful

tools for raw development because they significantly increase your programming muscle.

• Collection: a group of individual elements. – A List must hold the elements in a particular

sequence, – and a Set cannot have any duplicate elements.

• Map: a group of key-value object pairs. – Key must be unique

Page 3: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality
Page 4: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

import java.util.*; public class PrintingContainers {

static Collection fill(Collection c) { c.add("dog"); c.add("dog"); .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())); System.out.println(fill(new HashSet())); System.out.println(fill(new HashMap())); }

} ///:~toString equals hashCode

[dog, dog, cat]

[dog, cat]

{dog=Spot, cat=Rags}

Page 5: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Container disadvantage:unknown typeWhen you put an object into a container, the

object is upcasted to Object, and therefore the type information is lost.

1. Consequently, there’s no restriction on the type of object that can be put into your container, for example, you mean the container to hold only, say, cats. Someone could just as easily put a dog into it.

2. Since the container only knows what it holds is a reference to an object. You must perform a downcast to the correct type before you use it.

Page 6: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Container disadvantage:unknown typepublic class Cat {

private int catNumber; Cat(int i) { catNumber = i; } void print() { System.out.println("Cat #" + catNumber);

} } ///:~ //: c09:Dog.java public class Dog {

private int dogNumber; Dog(int i) { dogNumber = i; } void print() { System.out.println("Dog #" + dogNumber); }

} ///:~

Page 7: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Container disadvantage:unknown typeimport java.util.*; public class CatsAndDogs @SuppressWarnings("unchecked") {

public static void main(String[] args) { ArrayList cats = new ArrayList(); for(int i = 0; i < 7; i++) cats.add(new Cat(i)); // Not a problem to add a dog to cats: cats.add(new Dog(7)); for(int i = 0; i < cats.size(); i++) ((Cat)cats.get(i)).print(); // Dog is detected only at run-time }

} ///:~

Page 8: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Generics and type-safe containers

• One of the problems of using pre-Java SE5 containers was that the compiler allowed you to insert an incorrect type into a container.

• With generics, you’re prevented, at compile time, from putting the wrong type of object into a container.

Page 9: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

using Java generics import java.util.*; public class CatsAndDogs { public static void main(String[] args) {

ArrayList<Cat> cats = new ArrayList<Cat>();for(int i = 0; i < 7; i++) cats.add(new Cat(i)); // unable to add a dog to cats: !! cats.add(new Dog(7)); for(int i = 0; i < cats.size(); i++)

cats.get(i).print(); // Dog is detected only at run-time

} } ///:~

Page 10: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Making a type-consciousArrayList//: c11:MouseList.java // A type-conscious List. import java.util.*; public class MouseList {

private List list = new ArrayList(); public void add(Mouse m) { list.add(m); } public Mouse get(int index) {

return (Mouse)list.get(index); } public int size() { return list.size(); }

} ///:~templates

ArrayList<Mouse>

Page 11: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Generics and type-safe containersimport java.util.*;

public class ApplesAndOrangesWithGenerics {

public static void main(String[] args) {

ArrayList<Apple> apples = new ArrayList<Apple>();

for(int i = 0; i < 3; i++)

apples.add(new Apple());

// Compile-time error:

// apples.add(new Orange());

for(int i = 0; i < apples.size(); i++)

System.out.println(apples.get(i).id());

// Using foreach:

for(Apple c : apples)

System.out.println(c.id());

}

}

Page 12: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

import java.util.*; public class PrintingContainers {

static Collection<String> fill(Collection<String> c) { c.add("dog"); c.add("dog"); c.add("cat"); return c;

} static Map<String,String> fill(Map<String,String> 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<String> ())); System.out.println(fill(new HashSet<String> ())); System.out.println(fill(new HashMap<String,String>

())); }

} ///:~toString equals hashCode

[dog, dog, cat]

[dog, cat]

{dog=Spot, cat=Rags}

Page 13: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Iterators• Iterators provide a unified way to

put elements in or get elements out.

1. Ask a container to pass you an Iterator using a method called iterator( ).

• This Iterator will be ready to return the first element by next( ) method.

2. Get the next object in the sequence with next( ).

3. Chexk if there are any more objects in the sequence with hasNext( ).

4. Remove the last element returned by the iterator with remove( ).

Page 14: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

//: c09:CatsAndDogs2.java // Simple container with Iterator. import java.util.*; public class CatsAndDogs2 {

public static void main(String[] args) { ArrayList<Cat> cats = new ArrayList<Cat> (); for(int i = 0; i < 7; i++)

cats.add(new Cat(i));

Iterator<Cat> e = cats.iterator(); while(e.hasNext())

e.next().print(); }

} ///:~

Page 15: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

List functionalityList (interface)

– Order is the most important feature of a List; it promises to maintain elements in a particular sequence.

– List adds a number of methods to Collection that allow insertion and removal of elements in the middle of a List.

ArrayList– A List implemented with an array. – Allows rapid random access to elements– Slow when inserting and removing elements from the

middle

LinkedList– Provides optimal sequential access, with inexpensive

insertions and deletions from the middle of the List. – Relatively slow for random access. (Use ArrayList

instead.) – Additional methods: addFirst( ), addLast( ), getFirst( ),

getLast( ), removeFirst( ), and removeLast( )

Page 16: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Making a stack from a LinkedList

import java.util.*; public class StackL<T> {

private LinkedList<T> list = new LinkedList<T> (); public void push(T v) { list.addFirst(v); } public Object top() { return list.getFirst(); } public Object pop() { return list.removeFirst(); }

public static void main(String[] args) { StackL<Integer> stack = new StackL<Integer> (); for(int i = 0; i < 10; i++)

stack.push(new Integer(i) ); System.out.println(stack.top());

System.out.println(stack.top()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop());

} } ///:~

Page 17: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Set functionality • HashSet , TreeSet and LinkedHashSet

• Set has exactly the same interface as Collection, so there isn’t any extra functionality like Lists, the Set is exactly a Collection.

• It just has different behavior. A Set refuses to hold more than one instance of each object value. (so we need implement equals() method)

• When creating your own types, you must define:

– TreeSet: equals() method , implement the Comparable interface and define the compareTo( ) method.

– HashSet: equals() method, hashCode() method

Page 18: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Map functionality

• Different types of Maps in JDK: HashMap, TreeMap, LinkedHashMap, WeakHashMap, and

IdentityHashMap. • Hashing is the most commonly used way to store elements in a map.• • When creating your own types for keys, you must define:

– TreeMap: equals() method , implement the Comparable interface and define the compareTo( ) method.

– HashMap: equals() method, hashCode() method

• The put(Object key, Object value) method adds a key-value pair into a container.

• get(Object key) gets the value corresponding to the given key.

• You can also test a Map to see if it contains a key or a value with containsKey( ) and containsValue( ).

Page 19: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Map functionality

import java.util.*; class Counter {

int i = 1; public String toString() { return Integer.toString(i); }

} public class Statistics {

public static void main(String[] args) { HashMap<Integer,Counter> hm = new

HashMap<Integer,Counter> (); for(int i = 0; i < 10000; i++) {

// Produce a number between 0 and 20: Integer r = new Integer((int)

(Math.random() * 20));

if(hm.containsKey(r)) hm.get(r).i++; else hm.put(r, new Counter());

} System.out.println(hm);

} } ///:~

Page 20: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Map functionality

• When a HashMap object is printed, the HashMap toString( ) method moves through all the key-value pairs and calls the toString( ) for each one.

• {15=529, 4=488, 19=518, 8=487, 11=501, 16=487, 18=507, 3=524, 7=474, 12=485, 17=493, 2=490, 13=540, 9=453, 6=512, 1=466, 14=522, 10=471, 5=522, 0=531}

Page 21: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Map functionality

• You might wonder at the necessity of the class Counter, Why not use int or Integer?

• Well, you can’t use an int because all of the containers can hold only Object references.

– After you’ve seen containers, the wrapper classes might begin to make a little more sense to you, since you can’t put any of the primitive types in containers.

• However, Java wrappers(Integer) is constant objects. That is, there’s no way to change a value once a wrapper object has been created.

Page 22: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Hashing and hash codes• In Statistics.java, a standard library class (Integer) was

used as a key for the HashMap. It worked because it has all the necessary wiring to make it behave correctly as a key.

• But a common pitfall occurs with HashMaps when you create your own classes to be used as keys.

Page 23: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Map functionality

import java.util.*; class MyKey {

private int id; public MyKey(int i) { id=i; }public String toString() { return “ID”+Integer.toString(id); }

} class Counter {

int i = 1; public String toString() { return Integer.toString(i); }

} public class Statistics1 {

public static void main(String[] args) { HashMap<MyKey,Counter> hm = new

HashMap<MyKey,Counter> (); for(int i = 0; i < 100; i++) {

// Produce a number between 0 and 20: MyKey r = new MyKey ((int)(Math.random() * 20)); if(hm.containsKey(r)) hm.get(r).i++; else hm.put(r, new Counter());

} System.out.println(hm);

} } ///:~

Page 24: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

• C:\Java\jdk1.5.0>bin\java Statistics1{ID19=1, ID12=1, ID18=1, ID2=1, ID4=1, ID13=1, ID3=1, ID10=1, ID3=1,

ID11=1, ID3=1, ID1=1, ID14=1, ID19=1, ID10=1, ID16=1, ID2=1, ID17=1, ID11=1, ID7=1, ID12=1, ID2=1, ID10=1, ID10=1, ID8=1, ID13=1, ID2=1, ID0=1, ID0=1, ID16=1, ID13=1, ID5=1, ID0=1, ID6=1, ID7=1, ID9=1, ID10=1, ID11=1, ID12=1, ID13=1, ID12=1, ID5=1, ID11=1, ID7=1, ID4=1, ID15=1, ID13=1, ID0=1, ID3=1, ID5=1, ID6=1, ID14=1, ID4=1, ID9=1, ID6=1, ID18=1, ID13=1, ID16=1, ID17=1, ID15=1, ID14=1, ID7=1, ID4=1, ID12=1, ID0=1, ID5=1, ID17=1, ID10=1, ID5=1, ID14=1, ID4=1, ID0=1, ID14=1, ID12=1, ID13=1, ID0=1, ID3=1, ID4=1, ID1=1, ID9=1, ID0=1, ID2=1, ID0=1, ID16=1, ID2=1, ID0=1, ID2=1, ID5=1, ID4=1, ID3=1, ID7=1, ID9=1, ID10=1, ID2=1, ID14=1, ID18=1, ID16=1, ID8=1, ID6=1, ID16=1}

The problem is that MyKey is inherited from the common root class Object. It is Object’s hashCode( ) method that is used, and by default it just uses the address of its object.

Thus, the first instance of MyKey (3) does not produce a hash code equal to the hash code for the second instance of MyKey (3) that we tried to use as a lookup.

Page 25: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

• You not only need to override hashCode( ), but also need to override the equals( ). equals( ) is used by the HashMap when trying to determine if your key is equal to any of the keys in the table.

• A proper equals( ) must satisfy the following five conditions:– Reflexive: For any x, x.equals(x) should return true. – Symmetric: For any x and y, x.equals(y) should return true if

and only if y.equals(x) returns true. – Transitive: For any x, y, and z, if x.equals(y) returns true and

y.equals(z) returns true, then x.equals(z) should return true. – Consistent: For any x and y, multiple invocations of x.equals(y)

consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified.

– For any non-null x, x.equals(null) should return false.

• When creating your own types, you must ensure that:If a.equals(b) then a.hashCode() =b.hashCode()

Page 26: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

import java.util.*; class MyKey {

private int id; public MyKey(int i) { id=i; }

public String toString() { return “ID”+Integer.toString(id); }

public int hashCode() { return id; }

public boolean equals(Object o) { return (o instanceof MyKey) && (id

==((MyKey)o).id); }

} class Counter {

int i = 1; public String toString() { return Integer.toString(i); }

}

Page 27: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

public class Statistics1 { public static void main(String[] args) { HashMap<MyKey,Counter> hm = new

HashMap<MyKey,Counter>();

for(int i = 0; i < 100; i++) { // Produce a number between 0 and 20:

MyKey r = new MyKey ((int)(Math.random() * 20));

if(hm.containsKey(r)) hm.get(r).i++; else hm.put(r, new Counter()); } System.out.println(hm);

} } ///:~

C:\Java\jdk1.5.0>bin\java Statistics2

{ID15=5, ID4=4, ID19=7, ID8=3, ID11=11, ID16=9, ID18=7, ID3=3, ID7=4, ID12=5, ID17=1, ID2=5, ID13=5, ID9=9, ID6=4, ID1=4, ID14=3, ID10=5, ID5=2, ID0=4}

Page 28: 11: Holding Your Objects Introduction to containers Container disadvantage: unknown type Iterators Container taxonomy Collection functionality List functionality

Exercises1.Modify the example class StackL(ppt page15)

to eliminate generics so that the stack can hold different wrapping class data(String, Integer, Double etc.) and the value we push or pop is printed to the scrren, and when we try to pop from an empty stack, an error message is shown.

2.Modify the example Statistics.java to count the number of character from ‘A’ to ‘Z’ of the string inputted as command argument. (use s.charAt(i) to get separate character)