Upload
isaac-lane
View
224
Download
4
Embed Size (px)
Citation preview
ADSA: Generics/2 1
241-423 Advanced Data Structures and Algorithms
• Objective– to describe basic forms of generic classes,
interfaces, and methods for searching and sorting
Semester 2, 2013-2014
2. Generic Classes and Methods
ADSA: Generics/2 2
Contents1. The Object Superclass
2. Generalizing Sequential Search
3. General Collections
4. Better Collections with Generics
5. Generic Interfaces
6. The Comparable Interface
7. Generic Methods
8. Generic Searching / Sorting
ADSA: Generics/2 3
1. The Object Superclass
• Every class is a subclass (or sub-subclass, sub-sub-subclass, etc) of the Object class.
ADSA: Generics/2 4
Object Class Methods
• Boolean equals(Object obj)– is obj “equal to” this object?
• String toString()– returns a string representation of this object
Object o = new Object();
o.equals(obj);
String s = o.toString();
ADSA: Generics/2 5
2. Generalizing Sequential Search
• Our seqSearch() method from Part (1) can only search int[] arrays for an integer target– the code is shown again on the next slide
• A generalized version uses an Object array and an Object target– see slide 7
ADSA: Generics/2 6
Sequential Search with int
public static int seqSearch(int[] arr, int first, int last, int target)
{ // scan elements in the range // first <= i < last; test for a match for (int i = first; i < last; i++) if (arr[i] == target) return i;
// match not found return -1;}
ADSA: Generics/2 7
Sequential Search with Object
public static int seqSearch(Object[] arr, int first, int last, Object target){ // scan elements in the range // first <= i < last; test for a match for (int i = first; i < last; i++) if (arr[i].equals(target)) return i;
// match not found return -1;}
continued
ADSA: Generics/2 8
• This generalized search method can deal with arrays of any subclass (or sub-subclass, etc) of Object– now seqSearch() can search polymorphic data
structures
Object[] arr = new Object[3];arr[0] = new Date();arr[1] = new HourlyEmployee("andrew");arr[2] = new Integer(4);
seqSearch(arr, 0, 3, new Integer(3) );
ADSA: Generics/2 9
3. General Collections
• A general-purpose collection class stores different kinds of elements.
• One way to implement the collection is to store the elements as Object instances.
• Problems: – A cast is required to access an element;– Accessing an element with the wrong cast will often
cause a runtime error
ADSA: Generics/2 10
Object-based Store Examplepublic class Store{ private Object value; // data
public Store () { value = null; }
public Object getValue() { return value; }
// set v as the new stored value public void setValue(Object v) { value = v; }
public String toString() { return "value = " + value; }}
ADSA: Generics/2 11
Using the Store
Store s1 = new Store();s1.setValue("hello");String msg1 = (String) s1.getValue();
Store s2 = new Store();s2.setValue( new Time24() );Time24 t2 = (Time24) s2.getValue();
String msg2 = s2.getValue(); //?
Time24 t1 = (Time24) s1.getValue();
causes a runtime error
ADSA: Generics/2 12
4. Better Collections with Generics
• In a generic collection, instances use a generic type T, which is fixed at compile-time to be a particular class.
• No cast is required when accessing a collection element – no possibility of runtime errors– any errors are caught at compile time, which
means they can be fixed easily
ADSA: Generics/2 13
Generic Store Examplepublic class Store<T>{ private T value; // data of type/class T
public Store () { value = null; }
// return the stored value as type T public T getValue() { return value; }
// update the stored value public void setValue(T v) { value = v; }
public String toString() { return "Value = " + value; }}
All these T'smust be the same class/typewhen a Storeobject is used.
ADSA: Generics/2 14
Using the Store
Store<String> ss = new Store<String>();ss.setValue("hello");String msg = ss.getValue();
Store<Time24> st = new Store<Time24>();st.setValue( new Time24() );Time24 t = st.getValue();
String msg2 = st.getValue(); // warning
Time24 t1 = ss.getValue();
causes a compile time error
ADSA: Generics/2 15
5. Generic Interfaces
• Interfaces can use generic types:
public interface Accumulator<T>{ public void add(T v); }
• Using the interface:public class Foo implements
Accumulator<String>
ADSA: Generics/2 16
AccumulatorTime Class
public class AccumulatorTime implements Accumulator<Time24>{ private Time24 total; // time total
public AccumulatorTime () { total = new Time24(); } // time is 0:00
public Time24 getTotal() { return total; }
// add time v to total public void add(Time24 v) { total.addTime(v.getHour()*60 + v.getMinute()); }}
store a Time24 total
ADSA: Generics/2 17
AccumulatorNumber Class
public class AccumulatorNumber implements Accumulator<Number>{ private double total;
public AccumulatorNumber () { total = 0.0; }
public double getTotal() { return total; }
// add v to total as a double public void add(Number v) { total = total + v.doubleValue(); }}
store a Number total
ADSA: Generics/2 18
Using the Accumulators
import ds.time.Time24;
public class UsingAccumlators{ public static void main (String[] args) { Integer[] intArr = {7, 1, 9, 3, 8, 4}; String[] strArr = {"3:45", "2:30", "5:00"};
AccumulatorNumber accNumber = new AccumulatorNumber(); AccumulatorTime accTime = new AccumulatorTime();
:
ADSA: Generics/2 19
for (int i = 0; i < intArr.length; i++) accNumber.add(intArr[i]); System.out.println("Numeric total is " + accNumber.getTotal());
for (int i = 0; i < strArr.length; i++) accTime.add(Time24.parseTime(strArr[i])); System.out.println("Time total is " + accTime.getTotal()); }}
Numeric total is 32Time total is 11:15
ADSA: Generics/2 20
6. The Comparable Interface
• The Comparable<T> interface is a standard way to compare objects.
• The interface defines a single method:
public interface Comparable<T>{ int compareTo(T item); }
ADSA: Generics/2 21
compareTo() Meaning
• compareTo() should return an integer that is negative, 0, or positive.
• Meaning:– obj.compareTo(item) < 0 when obj < item– obj.compareTo(item) == 0 when obj == item– obj.compareTo(item) > 0 when obj > item
ADSA: Generics/2 22
Time24 Class with Comparable
public class Time24 implements Comparable<Time24>{ . . . public int compareTo(Time24 item) //compares times { int time = hour*60 + minute; // use minutes int ttime = item.hour*60 + item.minute;
// compare, returning -1, 0, or 1 if (time < ttime) return -1; else if (time == ttime) return 0; else return 1; }}
ADSA: Generics/2 23
7. Generic Methods
• A generic method includes a generic type modifier <T>:
public static <T> T max(T a, T b)
/* compare two objects of the same type/class, return the biggest */
{ ... }
continued
ADSA: Generics/2 24
• The modifier <T> tells the compiler that T is a generic type, and the compiler checks that objects a and b and the return type are all the same.
• There's no need for <T> if the method is inside a generic <T> class, such as setValue() on slide 13.
ADSA: Generics/2 25
A Bad Generic max()
• javac prints an "unchecked cast" warning because this method is not type-safe– the code may cause a run-time error because a's class may
not implement Comparable when object a is cast at run time
public static <T> T max(T a, T b){ if (((Comparable<T>)a).compareTo(b) > 0) return a; else return b;}
the compiler cannotbe sure that the typingis correct
ADSA: Generics/2 26
// Rectangle does not implement// Comparable<Rectangle>
Rectangle rectA = new Rectangle(4,5);Rectangle rectB = new Rectangle(6,2);
Rectangle r = max(rectA, rectB); // compiler time warning; // exception at runtime
ADSA: Generics/2 27
A Good Generic max()
public static <T extends Comparable<T>> T max(T a, T b){ if (a.compareTo(b) > 0) return a; else return b;}
T is a bounded type
The bound specifies that the generic type T must implement the Comparable<T> interface.
ADSA: Generics/2 28
A Better Generic max()? is a wildcard (unknown)
public static <T extends Comparable<? super T>> T max(T a, T b){ if (a.compareTo(b) > 0) return a; else return b;}
"?" and "super" mean that T, or some superclass of T, must implement the Comparable interface.
ADSA: Generics/2 29
8. Generic Searching/Sorting
• A generic sort method takes an array of type T. A generic search method also uses a target of type T.
• If the code uses compareTo() to compare objects, then the method must include the bounded wildcard modifier:
<T extends Comparable<? super T>>
ADSA: Generics/2 30
Generic Selection Sort
public static <T extends Comparable<? super T>> void selectionSort(T[] arr){ // index of smallest element in sublist int smallIndex; int idx; int n = arr.length; // idx has range 0 to n-2 for (idx = 0; idx < n-1; idx++) { // scan sublist starting at index idx smallIndex = idx; :
ADSA: Generics/2 31
// go through arr[idx+1] to arr[n-1] for (int j = idx+1; j < n; j++) /* if smaller element found, assign smallIndex to that position */ if (arr[j].compareTo(arr[smallIndex]) < 0) smallIndex = j;
// swap smallest element into arr[idx] T temp = arr[idx]; arr[idx] = arr[smallIndex]; arr[smallIndex] = temp; }}
ADSA: Generics/2 32
Generic binSearch()
public static <T extends Comparable<? super T>> int binSearch(T[] arr, int first, int last, T target){ int mid; // midpoint index T midvalue; // holds arr[mid]
// save original value of last int origLast = last;
// test for nonempty sublist while (first < last) { mid = (first+last)/2; midvalue = arr[mid]; :
ADSA: Generics/2 33
if (target.compareTo(midvalue) == 0) return mid; // found a match // find which sublist to search else if (target.compareTo(midvalue) < 0) // search lower sublist. set last last = mid; else // search upper sublist. set first first = mid+1; } return -1; // target not found}
ADSA: Generics/2 34
Generic Sort Examplesimport ds.util.Arrays;import ds.time.Time24;
public class GenericSorting{ public static void main (String[] args) { String[] strArr = {"red", "green", "blue"}; Integer[] intArr = {40, 70, 50, 30};
Time24[] timeArr = { new Time24(14,15), new Time24(10, 45), new Time24(22,00), new Time24(3,30)};
SalaryEmployee[] emp = { new SalaryEmployee("Dunn, Moira","471-23-8092",800), new SalaryEmployee("Garcia, Avey" "398-67-1298",1200), new SalaryEmployee("Ye, Don", "682-76-1298",2000)}; :
ADSA: Generics/2 35
Arrays.selectionSort(strArr); System.out.println("Sorted strings: " + Arrays.toString(strArr));
Arrays.selectionSort(intArr); System.out.println("Sorted integers: " + Arrays.toString(intArr));
Arrays.selectionSort(timeArr); System.out.println("Sorted times: " + Arrays.toString(timeArr));
Arrays.selectionSort(emp); for (int i=0; i < emp.length; i++) System.out.println(emp[i].payrollCheck()); }}
ADSA: Generics/2 36
Output
ADSA: Generics/2 37
Employee and SalaryEmployee
public class Employee implements Comparable<Employee>
{ // vars are accessible by subclass methods protected String empName; :
// compare social security numbers public int compareTo(Employee obj) { return empSSN.compareTo(obj.empSSN); }}
continued
ADSA: Generics/2 38
public class SalaryEmployee extends Employee
{
// new vars
private double salary;
:
// no compareTo() method here
}