Introduction to Software Systems Honors Lecture #15: October 21, 2015 1/34
Generic classes and types Generic programming is the creation of programming constructs that can be usedwith many different types. For example, the ArrayList class uses the technique of generic programming. As a result, you can form array lists that collect elements of different types, such as ArrayList<String>, ArrayList<BankAccount> When declaring a generic class, you specify a type variable for each type parameter. Here is how the standard Java library declares the ArrayList class, using the type variable E for the element type: public class ArrayList<E> public ArrayList()... public void add(e element)...... Here, E is a type variable, not a Java reserved word. 2/34
Generic classes and types In order to use a generic class, you need to instantiate the type parameter, that is, supply an actual type. You can supply any class or interface type, for example ArrayList<BankAccount> ArrayList<Measurable> However, you cannot substitute any of the eight primitive types for a type parameter. It would be an error to declare: ArrayList<double> Use the corresponding wrapper class instead, such as ArrayList<Double> 3/34
Implementing generic types Simple generic class that stores pairs of objects, each of which can have an arbitrary type. This class can be useful when you implement a method that computes two values at the same time. A method cannot simultaneously return a String and an Integer, but it can return a single object of type Pair<String, Integer>. public class Pair<T, S> private T first; private S second; public Pair(T firstelement, S secondelement) first = firstelement; second = secondelement; public T getfirst() return first; public S getsecond() return second; 4/34
Interfaces A Java interface is a collection of abstract methods and constants. An abstract method is a method header without a method body. An abstract method can be declared using the modifier abstract, but because all methods in an interface are abstract, usually it is left off. An interface is used to establish a set of methods that a class will implement. None of the methods in an interface are given a definition (body). An interface cannot be instantiated. Methods in an interface have public visibility by default. A class formally implements an interface by: stating so in the class header providing implementations for every abstract method in the interface If a class declares that it implements an interface, it must define all methods in the interface. 5/34
Interfaces In addition to (or instead of) abstract methods, an interface can contain constants. When a class implements an interface, it gains access to all its constants. A class that implements an interface can implement other methods as well. A class can implement multiple interfaces. The interfaces are listed in the implements clause. The class must implement all methods in all interfaces listed in the header. 6/34
The Java API contains many helpful interfaces. The Comparable interface The Comparable interface contains one abstract method called compareto, which is used to compare two objects. The String class implements Comparable, giving us the ability to put strings in lexicographic order. Any class can implement Comparable to provide a mechanism for comparing objects of that type The value returned from compareto should be: negative is obj1 is less that obj2, 0 if they are equal, and positive if obj1 is greater than obj2. It's up to the programmer to determine what makes one object less than another. 7/34
Sorting an array of objects A sorting algorithm repeatedly compares elements and rearranges them if they are out of order. The rules for doing the comparison are different for each class, and the sorting algorithm should just call a method supplied by the class. If a class wants to enable sorting for its objects, it should implement the Comparable interface. We want to compare strings against strings, employees against employees, and so on. For that reason, the Comparable interface has a type parameter. public interface Comparable<T> int compareto(t other); For example, the String class implements Comparable<String> so that its compareto method has the signature int compareto(string other). 8/34
Comparing When calling x.compareto(y), the compareto method returns an integer value to indicate whether x or y should come first. A positive return value (not necessarily 1) indicates that x should come after y. A negative integer (not necessarily -1) is returned when x should come before y. If x and y are considered equal, the returned value is 0. Note that the return value can be any integer. That flexibility is useful because it allows you to return a difference of non-negative integers. public class Employee implements Comparable<Employee>... public int compareto(employee other) return getid() - other.getid(); // Ok if IDs always >= 0 9/34
Implementing Comparable You can implement the Comparable interface for your own classes as well. For example, to sort a collection of coins, the Coin class would need to implement this interface and declare a compareto method: public class Coin implements Comparable... public int compareto(object otherobject) Coin other = (Coin) otherobject; if (value < other.value) return -1; if (value == other.value) return 0; return 1;... 10/34
Example Suppose we have player objects with pairs (name, points) and we want to sort them according to the number of points. import java.util.*; public class Player implements Comparable<Player> private int points; private String name; Player(String name, int points) this.name = name; this.points = points; public int compareto(player other) if (this.points < other.points) return -1; // ascending else if (this.points > other.points) return 1; else // return 0; return this.name.compareto(other.name); 11/34
public String tostring() return // this.getclass().getname() + "(" + this.name + ":" + this.points; // + ")"; public static void main(string[] args) Player a = new Player("Tommy", 19); Player b = new Player("Troy", 19); Player c = new Player("Trevor", 19); Player d = new Player("Shea", 21); Player e = new Player("Lane", 24); System.out.println( c ); ArrayList<Player> players = new ArrayList<Player>(); players.add(c); players.add(b); Trevor:19 players.add(a); [Trevor:19, Troy:19, Tommy:19, Shea:21, Lane:24, Jack:14] [Jack:14, Tommy:19, Trevor:19, Troy:19, Shea:21, Lane:24] players.add(d); players.add(e); players.add(new Player("Jack", 14)); System.out.println( players ); Collections.sort( players ); System.out.println( players ); 12/34
Collections The Java collections framework provides implementations of common data structures. To make it easy to write code that is independent of the choice of data structures, the collections framework provides a number of common interfaces. A collection is an object that serves as a repository for other objects. A collection provides services for adding, removing, and otherwise managing the elements it contains. Sometimes the elements in a collection are ordered, sometimes they are not. Collections should be abstractions, that is, they should hide unneeded details. We want to separate the interface of the structure from its underlying implementation. This helps manage complexity and makes it possible to change the implementation without changing the interface. 13/34
Dynamic Structures A static data structure has a fixed size. This meaning is different from the meaning of the static modifier. Arrays are static; once you define the number of elements it can hold, the size doesn t change. A dynamic data structure grows and shrinks at execution time as required by its contents. A dynamic data structure is implemented using object references as links. Recall that an object reference is a variable that stores the address of an object. A reference also can be called a pointer. References often are depicted graphically: student John Smith 40725 3.58 14/34
Object references can be used to create links between objects. References as Links Suppose a class contains a reference to another object of the same class: class Node int info; Node next; References can be used to create a variety of linked structures, such as a linked list: 15/34
Intermediate nodes The objects being stored should not be concerned with the details of the data structure in which they may be stored. For example, the Student class should not have to store a link to the next Student object in the list. Instead, use a separate node class with two parts: a reference to an independent object a link to the next node in the list The internal representation becomes a linked list of nodes. Example: Magazine collection Magazine objects managed by the MagazineList class private inner class MagazineNode 16/34
//******************************************************************** // Magazine.java // Represents a single magazine. //******************************************************************** public class Magazine private String title; //----------------------------------------------------------------- // Sets up the new magazine with its title. //----------------------------------------------------------------- public Magazine(String newtitle) title = newtitle; //----------------------------------------------------------------- // Returns this magazine as a string. //----------------------------------------------------------------- public String tostring() return title; 17/34
//******************************************************************* // MagazineList.java // // Represents a collection of magazines. //******************************************************************* public class MagazineList private MagazineNode list; //---------------------------------------------------------------- // Sets up an initially empty list of magazines. //---------------------------------------------------------------- public MagazineList() list = null; 18/34
//---------------------------------------------------------------- // Creates a new MagazineNode object and adds it to the end of // the linked list. //---------------------------------------------------------------- public void add(magazine mag) MagazineNode node = new MagazineNode(mag); MagazineNode current; if (list == null) list = node; else current = list; while (current.next!= null) current = current.next; current.next = node; 19/34
//---------------------------------------------------------------- // Returns this list of magazines as a string. //---------------------------------------------------------------- public String tostring() String result = ""; MagazineNode current = list; while (current!= null) result += current.magazine + "\n"; current = current.next; return result; 20/34
//***************************************************************** // An inner class that represents a node in the magazine list. // The public variables are accessed by the MagazineList class. //***************************************************************** private class MagazineNode public Magazine magazine; public MagazineNode next; //-------------------------------------------------------------- // Sets up the node //-------------------------------------------------------------- public MagazineNode(Magazine mag) magazine = mag; next = null; 21/34
//******************************************************************* // MagazineRack.java // Driver to exercise the MagazineList collection. //******************************************************************* public class MagazineRack Output Time //---------------------------------------------------------------- Woodworking Today // Creates a MagazineList object, adds several magazines to the Communications of the ACM // list, then prints it. House and Garden //---------------------------------------------------------------- IEEE Computer public static void main(string[] args) MagazineList rack = new MagazineList(); rack.add(new Magazine("Time")); rack.add(new Magazine("Woodworking Today")); rack.add(new Magazine("Communications of the ACM")); rack.add(new Magazine("House and Garden")); rack.add(new Magazine("IEEE Computer")); System.out.println(rack); 22/34
A node can be inserted into a linked list with a few reference changes: Inserting a node Code that inserts newnode after the node pointed to by current. newnode.next = current.next; current.next = newnode; 23/34
Deleting a node A node can be removed from a linked list by changing the next pointer of the preceding node: 24/34
Other dynamic representations Doubly linked list: Linked list with a header node: 25/34
Queues A queue is a list that adds items only to the rear of the list and removes them only from the front It is a FIFO data structure: First-In, First-Out Analogy: a line of people at a bank teller s window Operations for a queue: enqueue dequeue empty - add an item to the rear of the queue - (or serve) remove an item from the front of the queue - returns true if the queue is empty 26/34
Stacks A stack ADT is also linear, like a list or a queue. Items are added and removed from only one end of a stack. It is therefore LIFO: Last-In, First-Out. Stack operations: push pop peek empty - add an item to the top of the stack - remove an item from the top of the stack - (or top) retrieves the top item without removing it - returns true if the stack is empty 27/34
GUI: mouse events Java divides event that are generated when using a mouse into two categories: mouse events mouse motion events When you click the mouse button over a Java GUI component, three events are generated: one when the mouse button is pushed down (mouse pressed) and two when it is let up (mouse released and mouse clicked). A mouse click is defined as pressing and releasing the mouse button in the same location. If you press the mouse button down, move the mouse, and then release the mouse button, a mouse clicked event is not generated. 28/34
GUI: mouse events Java divides event that are generated when using a mouse into two categories: mouse events mouse motion events mouse pressed mouse released mouse clicked mouse entered mouse exited the mouse button is pressed down the mouse button is released the mouse button is pressed down and released without moving the mouse in between the mouse pointer is moved onto (over) a component the mouse pointer is moved off of a component mouse moved mouse dragged the mouse is moved the mouse is moved while the mouse button is pressed down 29/34
GUI: mouse events Listeners for mouse events are created using the MouseListener and MouseMotionListener interfaces. A MouseEvent object is passed to the appropriate method when a mouse event occurs. For a given program, we may only care about one or two mouse events. To satisfy the implementation of a listener interface, empty methods must be provided for unused events. Example: The Dots program responds to one mouse event. It draws a green dot at the location of the mouse pointer whenever the mouse button is pressed. 30/34
//******************************************************************** // DotsPanel.java // // Represents the primary panel for the Dots program. //******************************************************************** import java.util.arraylist; import javax.swing.jpanel; import java.awt.*; import java.awt.event.*; public class DotsPanel extends JPanel private final int SIZE = 6; // radius of each dot private ArrayList<Point> pointlist; 31/34
//----------------------------------------------------------------- // Constructor: Sets up this panel to listen for mouse events. //----------------------------------------------------------------- public DotsPanel() pointlist = new ArrayList<Point>(); addmouselistener(new DotsListener()); setbackground(color.black); setpreferredsize(new Dimension(300, 200)); //----------------------------------------------------------------- // Draws all of the dots stored in the list. //----------------------------------------------------------------- public void paintcomponent(graphics page) super.paintcomponent(page); page.setcolor(color.green); for (Point spot : pointlist) page.filloval(spot.x-size, spot.y-size, SIZE*2, SIZE*2); page.drawstring("count: " + pointlist.size(), 5, 15); 32/34
//***************************************************************** // Listener for mouse events. //***************************************************************** private class DotsListener implements MouseListener //-------------------------------------------------------------- // Adds the current point to the list of points and redraws // the panel whenever the mouse button is pressed. //-------------------------------------------------------------- public void mousepressed(mouseevent event) pointlist.add(event.getpoint()); repaint(); //-------------------------------------------------------------- // Provide empty definitions for unused event methods. //-------------------------------------------------------------- public void mouseclicked(mouseevent event) public void mousereleased(mouseevent event) public void mouseentered(mouseevent event) public void mouseexited(mouseevent event) 33/34
//******************************************************************** // Dots.java // Demonstrates mouse events. //******************************************************************** import javax.swing.jframe; public class Dots //----------------------------------------------------------------- // Creates and displays the application frame. //----------------------------------------------------------------- public static void main(string[] args) JFrame frame = new JFrame("Dots"); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.getcontentpane().add(new DotsPanel()); frame.pack(); frame.setvisible(true); 34/34