COMP 213 Advanced Object-oriented Programming Lecture 28 Fun with - - PowerPoint PPT Presentation

comp 213
SMART_READER_LITE
LIVE PREVIEW

COMP 213 Advanced Object-oriented Programming Lecture 28 Fun with - - PowerPoint PPT Presentation

COMP 213 Advanced Object-oriented Programming Lecture 28 Fun with Generics More Parameters A class can have more than one type parameter. For example, a class of pairs: public class Pair<A,B> { private A first; private B second;


slide-1
SLIDE 1

COMP 213

Advanced Object-oriented Programming

Lecture 28

Fun with Generics

slide-2
SLIDE 2

More Parameters

A class can have more than one type parameter. For example, a class of pairs: public class Pair<A,B> { private A first; private B second; public Pair(A a, B b) { first = a; second = b; }

slide-3
SLIDE 3

class Pair, contd. public A getFirst() { return first; } public B getSecond() { return second; } } The constructor is declared without the < > notation; however, actual parameters ‘must’ (= ‘should’) be supplied when the constructor is called.

slide-4
SLIDE 4

Calling the Constructor

For example, in class Pair public static void main(String[] args) { Integer i = new Integer(8); Pair<Integer,Integer> p = new Pair(i,i); } gives the compile-time warning (not error!): terminal output Note: Pair.java uses unchecked or unsafe

  • perations.

Note: Recompile with -Xlint:unchecked for details.

slide-5
SLIDE 5

Calling the Constructor

For example, in class Pair public static void main(String[] args) { Integer i = new Integer(8); Pair<Integer,Integer> p = new Pair(i,i); } gives the compile-time warning (not error!): terminal output Note: Pair.java uses unchecked or unsafe

  • perations.

Note: Recompile with -Xlint:unchecked for details.

slide-6
SLIDE 6

javac -Xlint:unchecked Pair.java

terminal output Pair.java:37: warning: [unchecked] unchecked call to Pair(A,B) as a member of the raw type Pair Pair<Integer,Integer> p = new Pair(i,i); so we ‘need’ (not desperately, as it does compile): a better call Pair<Integer,Integer> p = new Pair<Integer,Integer>(i,i);

slide-7
SLIDE 7

javac -Xlint:unchecked Pair.java

terminal output Pair.java:37: warning: [unchecked] unchecked call to Pair(A,B) as a member of the raw type Pair Pair<Integer,Integer> p = new Pair(i,i); so we ‘need’ (not desperately, as it does compile): a better call Pair<Integer,Integer> p = new Pair<Integer,Integer>(i,i);

slide-8
SLIDE 8

Type Parameters

Within the class declaration, the formal parameter types act just like any other type, and can be used as types of parameters to methods and return types. They can also be used as ‘actual’ parameter types: public class Pair<A,B> { ... public Pair<B,A> swap() { return new Pair<B,A>(second,first); } }

slide-9
SLIDE 9

More Types of Type Parameters

Consider a class that lays out GUI components one above another in a column. This might be used for several different uses, e.g., setting menu items in a column setting Topic summaries (TopicIcons) in a column setting Messages (MessageIcons) in a column, etc. In each of these example applications, the list of components to be formatted is homogeneous: all TopicIcons, or all MessageIcons, etc. One way to do this would be to copy and paste the code from TopicIcon.java to the file MessageIcon.java, and do a global search/replace to replace all occurrences of ‘Topic’ with ‘Message’ (not very nice!)

slide-10
SLIDE 10

More Types of Type Parameters

Consider a class that lays out GUI components one above another in a column. This might be used for several different uses, e.g., setting menu items in a column setting Topic summaries (TopicIcons) in a column setting Messages (MessageIcons) in a column, etc. In each of these example applications, the list of components to be formatted is homogeneous: all TopicIcons, or all MessageIcons, etc. One way to do this would be to copy and paste the code from TopicIcon.java to the file MessageIcon.java, and do a global search/replace to replace all occurrences of ‘Topic’ with ‘Message’ (not very nice!)

slide-11
SLIDE 11

More Types of Type Parameters

Consider a class that lays out GUI components one above another in a column. This might be used for several different uses, e.g., setting menu items in a column setting Topic summaries (TopicIcons) in a column setting Messages (MessageIcons) in a column, etc. In each of these example applications, the list of components to be formatted is homogeneous: all TopicIcons, or all MessageIcons, etc. One way to do this would be to copy and paste the code from TopicIcon.java to the file MessageIcon.java, and do a global search/replace to replace all occurrences of ‘Topic’ with ‘Message’ (not very nice!)

slide-12
SLIDE 12

A Question

Could we use generic classes to avoid having to copy and paste code? public class IconView<C> extends JPanel { private C[] components; public void setComponents(C[] comps) { ... add(components[i]); } } C has to be a GUI component, i.e., a subclass of java.awt.Component.

slide-13
SLIDE 13

A Question

Could we use generic classes to avoid having to copy and paste code? public class IconView<C> extends JPanel { private C[] components; public void setComponents(C[] comps) { ... add(components[i]); } } C has to be a GUI component, i.e., a subclass of java.awt.Component.

slide-14
SLIDE 14

We can do it, but we need an extension...

public class IconView<C extends Component> extends JPanel { private C[] components; public void setComponents(C[] comps) { components = comps; ... add(components[i]); } } Any actual parameter must be a subclass of java.awt.Component

slide-15
SLIDE 15

We can do it, but we need an extension...

public class IconView<C extends Component> extends JPanel { private C[] components; public void setComponents(C[] comps) { components = comps; ... add(components[i]); } } Any actual parameter must be a subclass of java.awt.Component

slide-16
SLIDE 16

Constructors Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); TopicIcon[] topics = ...; topicView.setComponents(topics); ... IconView<MessageIcon> messageView = new IconView<MessageIcon>(); MessageIcon[] messages = ...; messageView.setComponents(messages);

slide-17
SLIDE 17

Type Checking Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); ... topicView.setComponents(topics); Formal parameter C is replaced by actual parameter TopicIcon. The compiler checks: TopicIcon is a subclass of Component topics is of type TopicIcon[] public class IconView<C extends Component> extends JPanel { ... public void setComponents(C[] comps) { ... } }

slide-18
SLIDE 18

Type Checking Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); ... topicView.setComponents(topics); Formal parameter C is replaced by actual parameter TopicIcon. The compiler checks: TopicIcon is a subclass of Component topics is of type TopicIcon[] public class IconView<C extends Component> extends JPanel { ... public void setComponents(C[] comps) { ... } }

slide-19
SLIDE 19

Type Checking Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); ... topicView.setComponents(topics); Formal parameter C is replaced by actual parameter TopicIcon. The compiler checks: TopicIcon is a subclass of Component topics is of type TopicIcon[] public class IconView<C extends Component> extends JPanel { ... public void setComponents(C[] comps) { ... } }

slide-20
SLIDE 20

Type Checking Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); ... topicView.setComponents(topics); Formal parameter C is replaced by actual parameter TopicIcon. The compiler checks: TopicIcon is a subclass of Component topics is of type TopicIcon[] public class IconView<C extends Component> extends JPanel { ... public void setComponents(C[] comps) { ... } }

slide-21
SLIDE 21

Type Checking Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); ... topicView.setComponents(topics); Formal parameter C is replaced by actual parameter TopicIcon. The compiler checks: TopicIcon is a subclass of Component topics is of type TopicIcon[] public class IconView<C extends Component> extends JPanel { ... public void setComponents(C[] comps) { ... } }

slide-22
SLIDE 22

Type Checking Again

IconView<TopicIcon> topicView = new IconView<TopicIcon>(); ... topicView.setComponents(topics); Formal parameter C is replaced by actual parameter TopicIcon. The compiler checks: TopicIcon is a subclass of Component topics is of type TopicIcon[] public class IconView<C extends Component> extends JPanel { ... public void setComponents(C[] comps) { ... } }

slide-23
SLIDE 23

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-24
SLIDE 24

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-25
SLIDE 25

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-26
SLIDE 26

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-27
SLIDE 27

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-28
SLIDE 28

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-29
SLIDE 29

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-30
SLIDE 30

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-31
SLIDE 31

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-32
SLIDE 32

More and More

class Extreme<A, B extends A, C extends B> { Extreme(){} public static void main(String[] args) { Extreme<Component,Container,JComponent> e = new Extreme<Component,Container,JComponent>(); } } This is correct, because JComponent is a subclass of Container, which is a subclass of Component.

slide-33
SLIDE 33

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-34
SLIDE 34

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-35
SLIDE 35

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-36
SLIDE 36

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-37
SLIDE 37

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-38
SLIDE 38

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-39
SLIDE 39

Interfaces

The keyword extends also applies to interfaces. For example public class RunnablePool<A extends Runnable> { private A[] pool; ... } This can be instantiated with any class that implements Runnable, e.g., RunnablePool<Consumer> consumerPool = new RunnablePool<Consumer>; RunnablePool<EchoHandler> echoPool = new RunnablePool<EchoHandler>;

slide-40
SLIDE 40

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-41
SLIDE 41

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-42
SLIDE 42

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-43
SLIDE 43

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-44
SLIDE 44

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-45
SLIDE 45

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-46
SLIDE 46

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-47
SLIDE 47

Generic Interfaces

Interfaces can themselves have type parameters. For example interface Listable<A> { public Vector<A> list(); } Classes implement this by providing a method called list that returns a Vector of some type A. E.g., class AVLTreeV1 implements Listable<Integer> { public Vector<Integer> list() { ... } ... }

slide-48
SLIDE 48

Exercise!

Implement this. Here’s a hint: in class AVLTreeV1 /** * Return a vector containing all the elements * in the tree. * @return the <b>sorted</b> list of all the * elements in the tree */ public Vector<Integer> list() { Vector<Integer> v = new Vector<Integer>(); if (root != null) { v = root.list(v); } return v; }

slide-49
SLIDE 49

Exercise!

in class AVLTreeNode (inner class of AVLTreeV1) /** * <em>Add</em> all the elements in this node * to the given vector. * @param the vector to add the values to * @return the vector containing all the * elements in v, followed by all the * elements in the left subtree, followed * by the internal label, followed by all * the elements in the right subtree */ Vector<Integer> list(Vector<Integer> v) { ... } Final hint: look at AVLTreeV1#printInorder().

slide-50
SLIDE 50

Generic AVL Trees

The AVL trees of the last couple of lectures stored integers in balanced binary search trees. This efficient data structure is useful for storing other data types; for example, Strings (recently used email addresses, perhaps) Topics in a Message Board forum (sorted by integer ID, perhaps) Employee records (sorted by Payroll number, or National Insurance number) So it would be useful to have a generic class AVLTree<T>. public class AVLTree<T> { ... }

slide-51
SLIDE 51

Generic AVL Trees

The AVL trees of the last couple of lectures stored integers in balanced binary search trees. This efficient data structure is useful for storing other data types; for example, Strings (recently used email addresses, perhaps) Topics in a Message Board forum (sorted by integer ID, perhaps) Employee records (sorted by Payroll number, or National Insurance number) So it would be useful to have a generic class AVLTree<T>. public class AVLTree<T> { ... }

slide-52
SLIDE 52

Generic AVL Trees

The AVL trees of the last couple of lectures stored integers in balanced binary search trees. This efficient data structure is useful for storing other data types; for example, Strings (recently used email addresses, perhaps) Topics in a Message Board forum (sorted by integer ID, perhaps) Employee records (sorted by Payroll number, or National Insurance number) So it would be useful to have a generic class AVLTree<T>. public class AVLTree<T> { ... }

slide-53
SLIDE 53

Generic AVL Trees

The AVL trees of the last couple of lectures stored integers in balanced binary search trees. This efficient data structure is useful for storing other data types; for example, Strings (recently used email addresses, perhaps) Topics in a Message Board forum (sorted by integer ID, perhaps) Employee records (sorted by Payroll number, or National Insurance number) So it would be useful to have a generic class AVLTree<T>. public class AVLTree<T> { ... }

slide-54
SLIDE 54

Generic AVL Trees

The AVL trees of the last couple of lectures stored integers in balanced binary search trees. This efficient data structure is useful for storing other data types; for example, Strings (recently used email addresses, perhaps) Topics in a Message Board forum (sorted by integer ID, perhaps) Employee records (sorted by Payroll number, or National Insurance number) So it would be useful to have a generic class AVLTree<T>. public class AVLTree<T> { ... }

slide-55
SLIDE 55

Generic AVL Trees

The AVL trees of the last couple of lectures stored integers in balanced binary search trees. This efficient data structure is useful for storing other data types; for example, Strings (recently used email addresses, perhaps) Topics in a Message Board forum (sorted by integer ID, perhaps) Employee records (sorted by Payroll number, or National Insurance number) So it would be useful to have a generic class AVLTree<T>. public class AVLTree<T> { ... }

slide-56
SLIDE 56

Generic AVLTrees

Consider the look-up method isIn(): in class AVLTree<T> public boolean isIn(T v) { ... if (v.equals(value)) { return true; } else if (v < value) { ... } } The parameter is some object belonging to the generic (formal parameter) class T. Because v is an object — an instance of a class — we use equals() to test equality.

  • Oops. We can’t do this: less-than only works for numbers.
slide-57
SLIDE 57

Generic AVLTrees

Consider the look-up method isIn(): in class AVLTree<T> public boolean isIn(T v) { ... if (v.equals(value)) { return true; } else if (v < value) { ... } } The parameter is some object belonging to the generic (formal parameter) class T. Because v is an object — an instance of a class — we use equals() to test equality.

  • Oops. We can’t do this: less-than only works for numbers.
slide-58
SLIDE 58

Generic AVLTrees

Consider the look-up method isIn(): in class AVLTree<T> public boolean isIn(T v) { ... if (v.equals(value)) { return true; } else if (v < value) { ... } } The parameter is some object belonging to the generic (formal parameter) class T. Because v is an object — an instance of a class — we use equals() to test equality.

  • Oops. We can’t do this: less-than only works for numbers.
slide-59
SLIDE 59

Generic AVLTrees

Consider the look-up method isIn(): in class AVLTree<T> public boolean isIn(T v) { ... if (v.equals(value)) { return true; } else if (v < value) { ... } } The parameter is some object belonging to the generic (formal parameter) class T. Because v is an object — an instance of a class — we use equals() to test equality.

  • Oops. We can’t do this: less-than only works for numbers.
slide-60
SLIDE 60

Generic AVLTrees

Consider the look-up method isIn(): in class AVLTree<T> public boolean isIn(T v) { ... if (v.equals(value)) { return true; } else if (v < value) { ... } } The parameter is some object belonging to the generic (formal parameter) class T. Because v is an object — an instance of a class — we use equals() to test equality.

  • Oops. We can’t do this: less-than only works for numbers.
slide-61
SLIDE 61

Generic AVLTrees

Consider the look-up method isIn(): in class AVLTree<T> public boolean isIn(T v) { ... if (v.equals(value)) { return true; } else if (v < value) { ... } } The parameter is some object belonging to the generic (formal parameter) class T. Because v is an object — an instance of a class — we use equals() to test equality.

  • Oops. We can’t do this: less-than only works for numbers.
slide-62
SLIDE 62

But . . .

But we can compare objects. For example, we can compare instances of class String by lexicographic (‘alphabetical’) order, or instances of class Date by chronological order, instances of List classes by prefix order (one list is less than another if the first is a prefix of the other), and so on. You can easily imagine a class of Employee Records whose instances could be compared by lexicographic order of name,

  • r by chronological order of Date of Birth, or by integer order of

age or payroll number, etc., etc.

slide-63
SLIDE 63

But . . .

But we can compare objects. For example, we can compare instances of class String by lexicographic (‘alphabetical’) order, or instances of class Date by chronological order, instances of List classes by prefix order (one list is less than another if the first is a prefix of the other), and so on. You can easily imagine a class of Employee Records whose instances could be compared by lexicographic order of name,

  • r by chronological order of Date of Birth, or by integer order of

age or payroll number, etc., etc.

slide-64
SLIDE 64

Interfaces Again

We would like to say that the internal labels of an AVL Tree (or a Binary Search Tree) can belong to any class that has some

  • rder on its instances.

For example, Strings with lexicographic order, Dates with chronological order, etc.. . . . . . which sounds like we need an interface (specifying some method that compares two instances).

slide-65
SLIDE 65

Interfaces Again

We would like to say that the internal labels of an AVL Tree (or a Binary Search Tree) can belong to any class that has some

  • rder on its instances.

For example, Strings with lexicographic order, Dates with chronological order, etc.. . . . . . which sounds like we need an interface (specifying some method that compares two instances).

slide-66
SLIDE 66

Interface java.lang.Comparable

public interface Comparable<T> { public int compareTo(T o); } Implementing classes need to provide a method that will compare an instance of the class to an instance of some class T. negative if the instance is less than the parameter; 0 if the instance is equal to the parameter; positive if the instance is greater than the parameter. Any class?

slide-67
SLIDE 67

Interface java.lang.Comparable

public interface Comparable<T> { public int compareTo(T o); } Implementing classes need to provide a method that will compare an instance of the class to an instance of some class T. negative if the instance is less than the parameter; 0 if the instance is equal to the parameter; positive if the instance is greater than the parameter. Any class?

slide-68
SLIDE 68

Interface java.lang.Comparable

public interface Comparable<T> { public int compareTo(T o); } Implementing classes need to provide a method that will compare an instance of the class to an instance of some class T. negative if the instance is less than the parameter; 0 if the instance is equal to the parameter; positive if the instance is greater than the parameter. Any class?

slide-69
SLIDE 69

Interface java.lang.Comparable

public interface Comparable<T> { public int compareTo(T o); } Implementing classes need to provide a method that will compare an instance of the class to an instance of some class T. negative if the instance is less than the parameter; 0 if the instance is equal to the parameter; positive if the instance is greater than the parameter. Any class?

slide-70
SLIDE 70

Interface java.lang.Comparable

public interface Comparable<T> { public int compareTo(T o); } Implementing classes need to provide a method that will compare an instance of the class to an instance of some class T. negative if the instance is less than the parameter; 0 if the instance is equal to the parameter; positive if the instance is greater than the parameter. Any class?

slide-71
SLIDE 71

Interface java.lang.Comparable

public interface Comparable<T> { public int compareTo(T o); } Implementing classes need to provide a method that will compare an instance of the class to an instance of some class T. negative if the instance is less than the parameter; 0 if the instance is equal to the parameter; positive if the instance is greater than the parameter. Any class?

slide-72
SLIDE 72

Implementing Comparable<T>

Generally, implementing classes compare instances to instances of the same class: in package java.lang public class Integer implements Comparable<Integer> { ... public int compareTo(Integer o) { ... } }

slide-73
SLIDE 73

Implementing Comparable<T>

Generally, implementing classes compare instances to instances of the same class: in package java.lang public class Integer implements Comparable<Integer> { ... public int compareTo(Integer o) { ... } }

slide-74
SLIDE 74

Implementing Comparable<T>

Generally, implementing classes compare instances to instances of the same class: in package java.lang public class Integer implements Comparable<Integer> { ... public int compareTo(Integer o) { ... } }

slide-75
SLIDE 75

Implementing Comparable<T>

in package java.util.Date public class Date implements Comparable<Date> { ... public long getTime() {... } public int compareTo(Date d) { return (int)this.getTime() - d.getTime(); } }

slide-76
SLIDE 76

Back to AVLTrees

class AVLTree< T extends Comparable<T> > { public boolean isIn(T v) { AVLTreeNode tn = root; ... if (v.compareTo(tn.value) == 0) { return true; } else if (v.compareTo(tn.value) < 0) { ... } }

slide-77
SLIDE 77

Back to AVLTrees

class AVLTree< T extends Comparable<T> > { public boolean isIn(T v) { AVLTreeNode tn = root; ... if (v.compareTo(tn.value) == 0) { return true; } else if (v.compareTo(tn.value) < 0) { ... } }

slide-78
SLIDE 78

Back to AVLTrees

class AVLTree< T extends Comparable<T> > { public boolean isIn(T v) { AVLTreeNode tn = root; ... if (v.compareTo(tn.value) == 0) { return true; } else if (v.compareTo(tn.value) < 0) { ... } }

slide-79
SLIDE 79

Another Example

An interface specifying ‘functions’ that take some input (of type A) and return some output (of type B): interface Function<A,B> { public B function(A a); } Implementing classes must have a method called function with

  • ne parameter (of any type) and some (non-void) return type.
slide-80
SLIDE 80

Another Example

An interface specifying ‘functions’ that take some input (of type A) and return some output (of type B): interface Function<A,B> { public B function(A a); } Implementing classes must have a method called function with

  • ne parameter (of any type) and some (non-void) return type.
slide-81
SLIDE 81

Another Example

An interface specifying ‘functions’ that take some input (of type A) and return some output (of type B): interface Function<A,B> { public B function(A a); } Implementing classes must have a method called function with

  • ne parameter (of any type) and some (non-void) return type.
slide-82
SLIDE 82

Another Example

An interface specifying ‘functions’ that take some input (of type A) and return some output (of type B): interface Function<A,B> { public B function(A a); } Implementing classes must have a method called function with

  • ne parameter (of any type) and some (non-void) return type.
slide-83
SLIDE 83

Functions

We can specialise this to functions whose return type is the same as the parameter type: interface IterableFunction<A> extends Function<A,A> { } This is the same as interface IterableFunction<A> { public A function(A a); }

slide-84
SLIDE 84

Functions

We can specialise this to functions whose return type is the same as the parameter type: interface IterableFunction<A> extends Function<A,A> { } This is the same as interface IterableFunction<A> { public A function(A a); }

slide-85
SLIDE 85

Example

An example of an implementing class that takes an Integer as input and returns an Integer as output: class DoubleInt implements IterableFunction<Integer> { public Integer function(Integer i) { return 2 * i; } }

slide-86
SLIDE 86

Example

An example of an implementing class that takes an Integer as input and returns an Integer as output: class DoubleInt implements IterableFunction<Integer> { public Integer function(Integer i) { return 2 * i; } }

slide-87
SLIDE 87

Another Example

A generic class implementing a generic interface. This class will repeatedly call function() a fixed number of times. class RepeatFunction<A> implements IterableFunction<A> { private int count; private IterableFunction<A> fun; RepeatFunction(int i, IterableFunction<A> f) { count = i; fun = f; }

slide-88
SLIDE 88

Another Example

public A function(A a) { int i = count; while (i-- > 0) { a = fun.function(a); } return a; } }

slide-89
SLIDE 89

Testing

We multiply by eight by doubling then doubling then doubling: public static void main(String[] args) { DoubleInt doubler = new DoubleInt(); RepeatFunction<Integer> rf = new RepeatFunction<Integer>(3, doubler); System.out.println(rf.function(5)); } rf will double three times. The result should be 40.

slide-90
SLIDE 90

Testing

We multiply by eight by doubling then doubling then doubling: public static void main(String[] args) { DoubleInt doubler = new DoubleInt(); RepeatFunction<Integer> rf = new RepeatFunction<Integer>(3, doubler); System.out.println(rf.function(5)); } rf will double three times. The result should be 40.

slide-91
SLIDE 91

Testing

We multiply by eight by doubling then doubling then doubling: public static void main(String[] args) { DoubleInt doubler = new DoubleInt(); RepeatFunction<Integer> rf = new RepeatFunction<Integer>(3, doubler); System.out.println(rf.function(5)); } rf will double three times. The result should be 40.

slide-92
SLIDE 92

Testing

We multiply by eight by doubling then doubling then doubling: public static void main(String[] args) { DoubleInt doubler = new DoubleInt(); RepeatFunction<Integer> rf = new RepeatFunction<Integer>(3, doubler); System.out.println(rf.function(5)); } rf will double three times. The result should be 40.

slide-93
SLIDE 93

Summary Multiple Type Parameters extends Generic Interfaces Next:

Generic methods