Big Java / Java Concepts Lab 20

advertisement
Big Java / Java Concepts Lab 14
Buttons
1. All problems in this lab are based on the HelloTester program:
/** File HelloTester.java */ import javax.swing.JFrame; public class
HelloTester {
public static void main(String args[])
{
JFrame frame = new HelloFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("HelloTester");
frame.setVisible(true);
}
} /** File HelloFrame.java */ import javax.swing.JFrame; import
javax.swing.JLabel; import java.awt.BorderLayout; import
java.awt.Font; public class HelloFrame extends JFrame {
public
HelloFrame()
{
message = "Hello, World!";
label
= new JLabel(message);
label.setFont(new Font("serif",
Font.PLAIN, DEFAULT_SIZE));
add(label, BorderLayout.CENTER);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
}
private String message;
private JLabel label;
private static int FRAME_WIDTH = 300;
private static int FRAME_HEIGHT = 300;
private static int DEFAULT_SIZE = 20;
}
In this problem, you need to add two buttons to the bottom of the frame, like this:
Follow these steps:
1. Make two instance variables of the class JButton:
private JButton smallerButton;
private JButton largerButton;
2. Create a method called createSouthPanel and place the following two lines
inside the method to initialize the variables with JButton objects:
smallerButton = new JButton("Smaller");
largerButton = new JButton("Larger");
3. Place the buttons into a panel:
JPanel southPanel = new JPanel();
southPanel.add(smallerButton);southPanel.add(largerButton);
4. Add the south panel to the frame:
add(southPanel, BorderLayout.SOUTH);
5. In the frame constructor, call the method createSouthPanel:
createSouthPanel();
Make these changes in your program. Run the program to confirm that the buttons
appear.
(a) What happens when you click the buttons? Why?
(b) Provide the source code for your createSouthPanel method.
2. Next, you need to connect the buttons to actions. For each button, carry out these
steps:
1. Create a class that implements the ActionListener interface and override the
actionPerformed method.
2. Make an object of that class.
3. Install that object as the action listener of the button.
Perform these steps one at a time.
When the "Larger" button is clicked, we want to increase the font size by 25
percent. When the "Smaller" button is clicked, we want to decrease it. To avoid
integer rounding errors, keep a floating-point instance variable fontSizeFactor
that is initialized with 1. Clicking on the buttons multiplies by 1.25 or 0.8 (because
0.8 = 1/ 1.25).
private double fontSizeFactor = 1;
Here is an appropriate action listener for the "Larger" button.
class LargerFontListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
fontSizeFactor = 1.25 * fontSizeFactor;
label.setFont(new Font("serif", Font.PLAIN,
(int) (DEFAULT_SIZE * fontSizeFactor)));
label.repaint();
}
}
Place this class inside the createSouthPanel method, since actionPerformed
needs to access the panel and fontSizeFactor variables.
To connect it to the "Larger" button, you need to create an object of this class and
set it as an action listener of the button. Place the following instructions into the
frame constructor:
ActionListener largerListener = new LargerFontListener();
largerButton.addActionListener(largerListener);
Add the code, compile the program, and run it. Don't add the code for the
"Smaller" button yet.
Click on both buttons several times. What happens?
3. Repeat the steps above for the "Smaller" button. Make an action listener class and
add an instance of that class as an action listener of the smallerButton. Run your
program. Both buttons should work.
Provide the complete code for the createSouthPanel method.
Layout Management
4. In the preceding program, the buttons were placed on the bottom of the frame, next
to each other. Change your program so that they are placed on the right of the
frame, one above the other other.
What is the code for the HelloFrame class now?
Menus
5. In this program, we will use a menu instead of a set of buttons to increase and
decrease the font size.
As with buttons, you need to solve two unrelated issues:


How to place the menu items
How to connect actions to the menu items.
In Java, there is a three-level hierarchy for menus.
1.
2.
A menu bar is attached to a window.
The menu bar contains menus, rectangular panels with menu strings inside
them.
3. Menus contain submenus and menu items.
Only menu items have actions associated with them.
Here are the instructions to build the menu for this program.
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu fontMenu = new JMenu("Font");
menuBar.add(fontMenu);
JMenuItem largerItem = new JMenuItem("Larger");
fontMenu.add(largerItem);
JMenuItem smallerItem = new JMenuItem("Smaller");
fontMenu.add(smallerItem);
Start again with the HelloFrame class.
Create a method called createMenu, and place these instructions inside this
method.
Run yor. (a)
Run your program and check that the menu works. Don't forget to call createMenu from
within the constructor. (a) What is the code for your HelloFrame class? (b) What
happens when you select a menu item?
6. Next, you need to attach actions to the menu items. This process is identical to
attaching actions to buttons.
Attach the actions to the two menu items and run your program. Check that
selecting the menu items respectively increases and decreases the font size.
What is the complete source code for your frame class now?
Combo Boxes
7. In this exercise, you will see how to offer a user a selection among multiple
choices. You can place all choices into a combo box.
To build such a combo box, you add items to it:
final JComboBox comboBox = new JComboBox();
comboBox.addItem("Small");
comboBox.addItem("Medium");
comboBox.addItem("Large");
comboBox.addItem("Extra Large");
Then place the combo box in the south end of the content pane.
add(comboBox, BorderLayout.SOUTH);
Add a createSouthPanel method and paste the lines indicated above inside the
method. Try it out. Don't forget to call the createSouthPanel method from within
the constructor. Run the program and compare it against the figure.
The program looks different. Why?
8. The border layout grows all items to their maximum size. To avoid this, enclose the
combo box inside a panel, even though it is a single item.
JPanel southPanel = new JPanel();
southPanel.add(comboBox);
add(southPanel, BorderLayout.SOUTH);
Try it out. Add the combo box to the frame of the HelloTester program. Compile
and run the program. Pull down the item list of the combo box to see the items.
What happens if you select one of the items?
9. To activate the combo box, you need to attach an action listener. The
actionPerformed method needs to determine which item the user selected.
class ComboListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String item = (String) comboBox.getSelectedItem();
. . .
}
}
You need to cast the return value of the getSelectedItem method to a String
because it is possible to put other objects, such as icons, into a combo box.
Now you simply set the correct font size, depending on the item string.
int messageSize = DEFAULT_SIZE;
if (item.equals("Small")) { messageSize = SMALL_SIZE; }
else if (item.equals("Medium")) { messageSize = MEDIUM_SIZE; }
else if (item.equals("Large")) { messageSize = LARGE_SIZE; }
else if (item.equals("Extra Large")) { messageSize =
EXTRA_LARGE_SIZE; }
label.setFont(new Font("serif", Font.PLAIN, messageSize));
label.repaint();
Define the size constants as follows:
public
public
public
public
static
static
static
static
final
final
final
final
int
int
int
int
SMALL_SIZE = 12;
MEDIUM_SIZE = 18;
LARGE_SIZE = 24;
EXTRA_LARGE_SIZE = 36;
Add the combo action listener and try out your program. When you select an item
from the combo box, the message should be displayed in the appropriate size.
Provide the complete source code for your createSouthPanel method.
Radio Buttons and Check Boxes
10. Radio buttons are another way to offer the user a selection among multiple
alternatives.
These buttons are called radio buttons because they work like the channel buttons
on a radio. When you select a radio button, the previously selected radio button is
turned off.
However, radio buttons take up more screen "real estate" than combo boxes and
therefore are best used when you need to offer users only a small selection.
Here are the instructions to construct two radio buttons:
helloButton = new JRadioButton("Hello");
goodbyeButton = new JRadioButton("Goodbye")
;
To get the "radio button" effect, where all other buttons are turned off when one of
the buttons is clicked, you need to place the buttons in a button group:
ButtonGroup group = new ButtonGroup();
group.add(helloButton);
group.add(goodbyeButton);
Finally, you want to turn the first button on:
helloButton.setSelected(true);
The button group is a logical grouping of the buttons. You still need to physically
lay out the buttons on the screen:
JPanel southPanel = new JPanel();
southPanel.add(helloButton);
southPanel.add(goodbyeButton);
add(southPanel, BorderLayout.SOUTH);
Add the two radio buttons to the frame of the HelloTester program. Add a
createSouthPanel method, just like you did in the previous problems. (a) What is the
code for your HelloFrame class? (b) Run the program. What happens when you click the
radio buttons?
11. Now change the message text when the user clicks a radio button. To assemble the
correct text, simply check which button is currently selected.
class MessageListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String message = "";
if (helloButton.isSelected()) message = "Hello";
else if (goodbyeButton.isSelected()) message = "Goodbye";
message = message + ", World!";
label.setText(message);
}
}
Note that you can attach the same action object to both buttons.
Add the action listener and attach it to the radio buttons. Run the program. Observe
how clicking the buttons changes the message text.
What is the complete source code for your HelloFrame class?
12. Check boxes are used to allow users to select a single logical alternative, typically
of the form "do X" or "do nothing". Here, a check box is used to allow the user to
specify whether the word "cruel" should be added to the message text:
Follow these steps to add the check box to the program.
1. Construct the check box.
cruelCheckBox = new JCheckBox("Cruel");
2. Attach the same action listener to the check box and the radio buttons.
cruelCheckBox.addActionListener(listener);
3. Add the check box to the south panel.
southPanel.add(cruelCheckBox);
4. In the actionPerformed method of the MessageAction class, check
if (cruelCheckBox.isSelected()) . . .
Run the program. Observe how clicking the check box changes the message text.
What is the complete source code for your HelloFrame class now?
Big Java / Java Concepts Lab 15
Throwing Exceptions
1. The BankAccount class has three methods with preconditions:
1. the constructor (initial balance must not be negative)
2. the withdraw method (withdrawal amount must not be greater than the balance)
3. the deposit method (deposit amount must not be negative)
Modify the code for the BankAccount class so that each of the three methods
throws an IllegalArgumentException if the precondition is violated.
What is the code for your modified BankAccount class?
2. Write a tester program that asks the user for:



the initial balance
an amount to deposit
an amount to withdraw
Have the program construct a BankAccount object and make the deposit and
withdrawal.
What is your tester program?
3. What happens when you make the following errors?
a. Construct an account with a negative balance
b. Withdraw more money than the account balance
c. Enter an illegal input (such as "ten" instead of "10")
Custom Exceptions
4. It is often a good idea to define your own exception class rather than rely on a
predefined class.
Define a class BankAccountException that can be used by the BankAccount class.
Your exception should be an unchecked exception.
What is the code for your exception class?
5. Why does it make sense to define the BankAccountException class as an
unchecked exception class?
6. Now modify the BankAccount class to throw BankAccountException objects
instead of IllegalArgumentException objects.
What is the code for your modified class?
7. If the BankAccountException class had been a checked exception, then what
changes would you need to make
a. in the definition of the exception class?
b. in the BankAccount methods?
Propagating Checked Exceptions
8. The DateFormat class of the standard Java library has a method
Date parse(String source)
that converts a string such as
"2/27/05 8:00 AM"
into an object of type Date:
DateFormat formatter = DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT);
String source = . . .;
Date d = formatter.parse(source);
If the source string is not in the correct format, then the parse method throws a
ParseException, which is a checked exception.
In this exercise, you will implement a class Appointment that stores the date and
description of an appointment:
public class Appointment
{
. . .
public String toString()
{
return "Appointment[date="
+ formatter.format(date)
+ "description=" + description + "; "
+ "]";
}
private Date date;
private String description;
private static DateFormat formatter =
DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT);
}
Supply a constructor
Appointment(String aDate, String aDescription)
that constructs an Appointment object from two strings. If the first string is not in a
legal format, your constructor should throw a ParseException.
9. Now you will create a class AppointmentBook that keeps an array list of
appointments. Part of the class has been provided for you:
import java.util.ArrayList;
import java.text.ParseException;
public class AppointmentBook
{
public AppointmentBook()
{
book = new ArrayList<Appointment>();
}
. . .
public void addAll(ArrayList<Appointment> list)
{
book.addAll(list);
}
public int getNumAppointments()
{
return book.size();
}
public Appointment getAppointment(int i)
{
return book.get(i);
}
public String toString()
{
String out = "";
for (Appointment a : book)
{
out = out + a.toString() + "\n";
}
return out;
}
private ArrayList<Appointment> book;
}
Add a method add, that adds a new appointment to the book. The method should
not catch the ParseException, but propagate it to the calling method.
public void add(String aDate, String aDescription)
Catching Exceptions
10. Write a program AppointmentBookTester whose main method asks the user to
enter a series of appointments. Add the appointments into an appointment book
object. If a parse error occurs in the add method, have the program instruct the user
to reenter the appointment.
Here is an outline of the main method, which does not yet catch any exceptions.
boolean done = false;
while (!done)
{
System.out.println("Next date (or -1 when done):");
String input1 = in.nextLine();
if (input1.equals("-1"))
done = true;
else
{
System.out.println("Description:");
String input2 = in.nextLine();
book.add(input1, input2);
}
}
System.out.println(book);
Add the appropriate try/catch block and test your program.
What is the complete code for your AppointmentBookTester class?
11. The preceding program is tedious to use because the user must type all
appointment data on the command-line. Improve the method so that the data can be
stored in a file.
Put the data in a text file, say, appts.txt, and then provide this file name when the
programs asks you to.
Create an AppointmentBookReader class that will read appointments stored in a
file. Use the following class:
import
import
import
import
java.util.Scanner;
java.text.ParseException;
java.io.FileReader;
java.io.IOException;
public class AppointmentBookReader
{
public AppointmentBookReader()
{
book = new AppointmentBook();
}
public AppointmentBook read(String filename)
throws IOException, ParseException
{
FileReader reader = new FileReader(filename);
Scanner in = new Scanner(reader);
while (in.hasNextLine())
{
String input1 = in.nextLine();
String input2 = in.nextLine();
book.add(input1, input2);
}
reader.close();
return book;
}
private AppointmentBook book;
}
To read from an appointment book, use the following code:
AppointmentBookReader bookReader = new AppointmentBookReader();
AppointmentBook book = bookReader.read(filename);
System.out.println(book);
Now change the AppointmentBookTester program so that it uses an
AppointmentBookReader.
If there is any exception, describe the nature of the exception in English. Print the
contents of the appointment book at the end of your program, whether or not there
is any exception.
What is the complete code for your AppointmentBookTester class?
12. Give an example of an input file that causes the AppointmentBookReader to throw
a ParseException.
13. Give an example of an input file that causes the AppointmentBookReader to throw
an NoSuchElementException.
The finally Clause
14. When there is an input error and the AppointmentBookReader class exits with an
exception, it should close its FileReader object by calling reader.close().
Modify the read method of the AppointmentBookReader class to close reader in
a finally clause.
What is the code for your modified read method?
Big Java / Java Concepts Lab 16
Reading and Writing Text Files
1. Write a program to store multiple memos in a file. Allow a user to enter a topic and
the text of a memo (the text of the memo is stored as a single line and thus cannot
contain a return character). Store the topic, the date stamp of the memo, and the
memo message.
Use a text editor to view the contents of the "memo.dat" file and to check that the
information is stored correctly.
Creating a java.util.Date object with no arguments will initialize the Date
object to the current time and date. A date stamp is obtained by calling the
Date.toString() method.
Part of the code of the program has been provided for you:
import . . . public class MemoPadCreator {
public static void
main(String args[])
{
Date now;
Scanner console =
new Scanner(System.in);
System.out.print("Output file: ");
String filename = console.nextLine();
try
{
PrintWriter out = . . .;
boolean done = false;
while (!done)
{
System.out.println("Memo topic (enter -1 to end):");
String topic = console.nextLine();
if (topic.equals("1"))
done = true;
else
{
System.out.println("Memo text:");
String message = console.nextLine();
/** Create the
new date object and obtain a dateStamp */
out.println(topic + "\n" + dateStamp + "\n" + message);
}
}
/** Close the output file*/
}
catch (. . .)
{
. . .
}
} }What is the code
for your program?
2. Modify your memo writing program to read multiple memos stored in a text file.
Memos are stored in three lines. The first line is the memo topic, the second line is
the date stamp, and the third line is the memo message. Display the memos one at a
time, and allow the user to choose to view the next memo (if there is one).
Part of the program code has been provided for you:
. . .
public class MemoPadReader
{
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
System.out.print("Input file: ");
String inputFileName = console.nextLine();
try
{
FileReader reader = . . .;
Scanner in = new Scanner(reader);
boolean done = false;
while (in.hasNextLine() && !done)
{
String topic = . . .;
String dateStamp = . . .;
String message = . . .;
System.out.println(topic + "\n" + dateStamp + "\n" +
message);
if (. . .) // You should only ask to display the next
memo if there are more memos in the file
{
System.out.println("Do you want to read the next
memo (y/n)?");
String ans = console.nextLine();
if (ans.equalsIgnoreCase("n"))
done = true;
}
}
reader.close();
}
catch (. . .)
{
. . .
}
}
}
What is the code for your program?
3. Modify your simple memo reader program. Use the JFileChooser to allow the
user to choose the file from which the memos will be read.
You can use the showOpenDialog method to enable the user to select a file to
"open". This method returns either JFileChooser.APPROVE_OPTION, if the user
has chosen a file, or JFileChooser.CANCEL_OPTION, if the user canceled the
selection.
If a file was chosen, then you call the getSelectedFile method to obtain a File
object that describes the file. Here is a complete example:
JFileChooser chooser = new JFileChooser();
FileReader in = null;
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{
File selectedFile = chooser.getSelectedFile();
reader = new FileReader(selectedFile);
. . .
}
What is the code for your program?
File Encryption
4. Write a program that encrypts (or decrypts) a file using an XOR cipher. An XOR
cipher encrypts a byte by performing an XOR bitwise operation with the byte to be
encrypted and a key. In Java, you can perform bitwise XOR using the ^ operator.
First, write a class XorEncryptor that encrypts or decrypts a file using an XOR
cipher. Part of the code of the class has been provided for you:
import . . .
/**
An encryptor encrypts files using a "XOR" cipher.
*/
public class XorEncryptor
{
/**
Constructs an encryptor.
@param aKey the encryption key
*/
public XorEncryptor(byte aKey)
{
key = aKey;
}
/**
Encrypts the contents of a file.
@param inFile the input file
@param outFile the output file
*/
public void encryptFile(String inFile, String outFile)
throws . . .
{
InputStream in = null;
OutputStream out = null;
try
{
in = . . .;
out = . . .;
encryptStream(in, out);
}
finally
{
/** Close the files */
}
}
/**
Encrypts the contents of a stream.
@param in the input stream
@param out the output stream
*/
public void encryptStream(InputStream in, OutputStream out)
throws . . .
{
boolean done = false;
while (!done)
{
int next = . . .;
if (next == -1) done = true;
else
{
byte b = (byte) next;
byte c = encrypt(b);
out.write(c);
}
}
}
/**
Encrypts a byte.
@param b the byte to encrypt
@return the encrypted byte
*/
public byte encrypt(byte b)
{
return . . .;
}
private byte key;
}
What is the complete code for the
XorEncryptor class?
5. Write a tester program that asks the user for the name of a file to encrypt (or
decrypt) and the name of the output file, and encrypts (or decrypts) the file. Note
that both operations are performed in exactly the same way. Your program should
also ask the user for the encryption key to use.
What is the complete code for your tester class?
6. Test your program. Create a file with the following content and encrypt it. Use "a"
as the encryption key.
This is a test for the XOR encryptor.
Open the encrypted file with a text editor. What are the contents of the encrypted
file?
7. Decrypt the file you just encrypted using your program. Don't forget to use "a" as
the decryption key. What is the output?
Command Line Arguments
8. Modify your testing program so that the input file, output file, and encryption key
are supplied on the command line.
What is the code for your modified tester class?
9. What command do you use to run your program to encrypt the file message.txt
into the file message.enc, using a as the encryption key? What command do you
use to decrypt the message.enc file?
Random Access Files
10. Create a program that reads and stores memos in a RandomAccessFile. To be able
to read and write memos in a random access file, the topic, date stamp and message
should each have a fixed size.
First, complete the code for the class MemoPad. You will write the tester program in
the next problem.
public class MemoPad
{
public MemoPad()
{
file = null;
}
public void open(String filename) throws IOException
{
. . .
}
/**
Gets the number of memos in the file.
@return the number of memos
*/
public int size() throws IOException
{
. . .
}
public void close() throws IOException
{
if (file != null) file.close();
file = null;
}
/**
Reads a memo record. The values of the last record read can
be obtained
with the getTopic, getDateStamp and getMessage methods.
@param n the index of the memo in the file
*/
public void read(int n) throws IOException
{
file.seek(. . .);
byte[] topic = new byte[MAX_CHARS_TOPIC];
byte[] date = new byte[MAX_CHARS_DATE];
byte[] message = new byte[MAX_CHARS_MSG];
/* Read the topic, date and message from the file (use the
method "read(byte[])".
Then, convert the byte arrays to strings and store them
in the variables currentTopic,
currentDateStamp and currentMessage
*/
}
public String getTopic()
{
return currentTopic; // returns the topic of the last memo
read
}
public String getDateStamp()
{
return currentDateStamp;
public String getDateStamp()
{
return currentDateStamp;
}
public String getMessage()
{
return currentMessage;
}
public void write(int n, String topic, String dateStamp, String
message) throws IOException
{
file.seek(. . .);
file.writeBytes(. . .); // "topic" should have a fixed size
file.writeBytes(. . .); // "dateStamp" should have a fixed size
file.writeBytes(. . .); // "message" should have a fixed size
}
/**
Adds white spaces to a string or cuts the string, so the string
has a length of exactly "size".
@param str the input string
@param size the desired size
@return the new string
*/
private String padOrTrim(String str, int size)
{
if (str.length() < size)
{
String pad = "";
for (int i = str.length(); i < size; i++)
pad = pad + " ";
return str + pad;
}
else
return str.substring(0, size);
}
private RandomAccessFile file;
private String currentTopic;
private String currentDateStamp;
private String currentMessage;
public static final
public static final
public static final
public static final
MAX_CHARS_DATE
+ MAX_CHARS_MSG;
}
int
int
int
int
MAX_CHARS_TOPIC = 25;
MAX_CHARS_DATE = 40;
MAX_CHARS_MSG = 250;
RECORD_SIZE = MAX_CHARS_TOPIC +
What is the complete code for this class?
11. Write a tester program that allows the user to add or display a memo. Memos
should be added to the end of the file. If the user wants to display a memo, a list of
the existing topics should be provided, so that the user can select which one he/she
wants to see. Complete the following program:
public class MemoPadTester
{
public static void main(String args[])
{
Scanner console = new Scanner(System.in);
System.out.println("Input file:");
String filename = console.nextLine();
try
{
MemoPad memoPad = new MemoPad();
memoPad.open(. . .);
boolean done = false;
while (!done)
{
System.out.print("Enter A to add a memo, D to display
an existing memo or Q to quit: ");
String choice = console.nextLine();
if (choice.equalsIgnoreCase("A"))
{
System.out.println("Topic (max 25 characters):");
String topic = console.nextLine();
String dateStamp = (new Date()).toString();
System.out.println("Message (max 250
characters):");
String message = console.nextLine();
memoPad.write(. . ., topic, dateStamp, message);
}
else if (choice.equalsIgnoreCase("D"))
{
if (memoPad.size() > 0)
{
// Display the list of topics
for (int i = 0; i < . . .; i++)
{
memoPad.read(. . .);
System.out.println(i + " " + . . .);
}
System.out.println("Enter the number of the memo
to display:");
int n = Integer.parseInt(console.nextLine());
memoPad.read(. . .);
System.out.println(. . .); // topic
System.out.println(. . .); // date stamp
System.out.println(. . .); // message
}
else
{
System.out.println("There are no memos in the
file.");
}
}
else if (choice.equalsIgnoreCase("Q"))
done = true;
}
memoPad.close();
}
catch (IOException exception)
{
System.out.println("Input/output error: " + exception);
}
}
}
What is the complete code for this class?
Object Streams
12. Write a program that writes memos to a file as object streams.The Memo class
should have fields to store a topic, a date stamp and the memo message. Allow a
user to enter multiple memos, supplying the topic and message. Your program
should provide the date stamp using the java.util.Date object. (Creating a Date
object with no arguments initializes the object to the current time and date).
Let the user choose the file name to which the memos are saved.
What is the code for your Memo class? Remember to implement the Serializable
interface!
13. Provide a tester program for your Memo class. Allow a user to enter multiple
memos, supplying the topic and message. Your program should provide the date
stamp using the java.util.Date object (creating a Date object with no
arguments initializes the object to the current time and date). Let the user choose
the file name to which the memos are saved.
After saving the file, your tester program should open the file and print out all
memos.
You can modify the program you created in problem 1.
What is the code for your tester program?
Big Java / Java Concepts Lab 17
Discovering Classes
1. You have been given an assignment to write a program to schedule classrooms in
your college's building. Classrooms can be reserved for classes, seminars, guest
speakers, and for meetings for clubs (such as the Java Users Group). Clubs can
meet only after 5 p.m. and only if the room is not needed by any other group. Each
group needing a classroom is given a priority. Classes in your college have the
highest priority, with clubs having the lowest priority. Some classes in your college
have higher priority over others, especially if the instructor has tenure. Classrooms
are characterized by size, amenities (overhead projectors, etc.) and comfortable
seats. Groups can specifically request a room by room number or simply give a
description of what they need. Groups also may request specific time slots or give a
range of acceptable time slots. Rooms are not available after 10 p.m. and before 5
a.m.
Make a list of classes that you may need for your program.
2. From your list of potential classes in your classroom-scheduling program, pick
three potential classes and identify their main responsibilities.
3. A CRC card describes a class, its responsibilities, and its collaborating classes. You
already identified the classes and responsibilities in the classroom-scheduling
program. Now you will identify the collaborating classes.
From your list of potential classes in your classroom-scheduling program, pick
three potential classes and identify their collaborators.
Relationships Between Classes
4. Using the list of classes for your classroom-scheduling program, identify any
objects that may use inheritance. List the superclasses (if any) followed by their
subclasses. If you see no need for inheritance, explain.
5. Inheritance can be described as an "is-a" relationship between classes. Aggregation
can be described as a "has-a" relationship. Identify any aggregation relations in the
classroom scheduling problem.
6. Identify the relationships between classes in the following code:
class GroceryBag extends BasicContainer
{
private Fruit[] fruits;
private Vegetable[] veggies;
. . .
public void addItem(Food item)
{
. . .
}
public Money computeTotal()
{
. . .
}
. . .
}
Inheritance
From which classes does GroceryBag inherit?
Aggregation
Identify any aggregation relationships (has-a relationship).
Dependency
On which classes does GroceryBag depend (uses relationship)?
Case Study
7. In this case study, you will develop a program to be used for ordering from an
online pizza restaurant. Allow the user the following choices: pizza size (small,
medium, or large), pizza crust type (thin or thick), pizza toppings, as well as small,
medium, and large drinks. The user may select specific toppings. A user can order
multiple pizzas and drinks. The order should include the customer's delivery
address. After taking the order, print an order slip that shows the order information
and total price.
Each topping has a price (for example, onions $1 and pepperoni $2). The price of a
pizza is the sum of the base price ($10 for a small pizza, $13 for a medium, and
$16 for a large pizza), plus the sum of the topping prices. The crust type doesn't
affect the price.
The price of a drink is the base price of the drink ($1 for soda, $2 for beer)
multiplied by a size factor (0.8 for small, 1.0 for medium, 1.2 for large drinks).
The delivery charge is $3. It is waived for pickup orders.
What classes can you identify using the "nouns from the requirements
specification" technique?
8. Not all of the classes are immediately visible in the requirements specification. In
our example, a pizza and a drink have common properties:


the price
the description that is printed on the order slip
In fact, if the restaurant were to start serving other items (such as bread sticks or
sandwiches), those items also would have a price and a description.
Define a suitable class that captures this commonality, and indicate how the classes
Pizza and Drink are related to this class.
9. What are the responsibilities and collaborators of the Order class?
10. You probably decided you need a class Topping. What is the code for your
Topping class? If you think you do not need a class Topping, explain why.
11. A very important class in your program is probably going to be called Pizza. What
is the code for your Pizza class. If you think you need superclasses and/or
subclasses of Pizza, supply the code for these classes too.
12.
Supply the code for your Drink class.
13. An order should contain a list of items (pizzas or drinks), so that the total price can
be calculated and the order can be formatted to be printed. Supply the code for your
Order class here.
14. Supply the code of any other classes you need to complete your program.
Big Java / Java Concepts Lab 18
Recursion
1. The factorial of a positive integer is the product of all nonnegative integers less than or
equal to that number. (The symbol for factorial is "!" - the exclamation mark.)
The formula for factorials for all nonnegative integers is:
n! = n * (n-1)! for n > 0;
Zero factorial is a special case and 0! = 1
From this definition, 5! is 120:1! = 1 * 0! = 12! = 2 * 1! = 23! = 3 * 2! = 64!
= 4 * 3! = 245! = 5 * 4! = 120
Write a recursive factorial method
long factorial(int n)
2. You can also compute the factorial values iteratively, without using recursion. Supply a
non-recursive factorial method.
3. Write a tester class that tests both solutions.
4. A formula for finding the greatest common divisor (GCD) of two numbers was
formulated by the mathematician Euclid around 300 BCE. The GCD of two
numbers is the largest number that will divide into both numbers without any
remainder. For example, the GCD of 12 and 16 is 4, the GCD of 18 and 12 is 6.
The basic algorithm is as follows:
Let a be the larger, b the smaller number. (We will assume that both values are
positive.)
Let c be the remainder that is obtained after dividing a through b.
If c is zero, then the GCD is b.
Otherwise, the GCD of a and b is the same as the GCD of b and c.
Recall that in Java, the % operator computes the remainder. For example, to
compute the GCD of 12 and 16, you compute
16 % 12 = 4
Now you need to compute the GCD of 12 and 4.
12 % 4 = 0
Therefore, the GCD is 4.
Write a recursive method that finds the GCD of two numbers using Euclid's
algorithm. (You may assume--or, better, assert--that both inputs are positive.)
5. Write a tester program for your GCD class.
Recursive Helper Methods
6. Write a program to draw the logarithmic spiral recursively.
The logarithmic spiral or Fibonacci spiral is a shape often found in nature. The nautilus
shell is the classic example of the logarithmic spiral. Seed patterns in sunflowers and
pinecones also demonstrate the spiral.
To construct a logarithmic spiral, begin with a "golden" rectangle. A golden rectangle
is a rectangle with sides of length A and φA, where φ (Phi) is the golden mean or the
value ( 1 + sqrt(5) ) / 2 or 1.61803 . . . A square with length equal to the smallest side
of the rectangle is drawn inside the rectangle. A quarter arc (arcAngle = 90 degrees)
is drawn within this square. The remaining rectangle is also a golden rectangle. This
remaining rectangle is divided into a square and another smaller golden rectangle. A
quarter arc connected to the previous arc is drawn inside the square, and the remaining
rectangle is once again subdivided with an arc drawn in it.
Create a panel in which to draw the spiral:
public class LogSpiralPanel extends JPanel
Given the dimensions of the panel, draw the largest golden rectangle that will fit within
the panel. Part of the code of the class has been provided for you:
import
import
import
import
import
java.awt.Graphics2D;
java.awt.Graphics;
java.awt.Rectangle;
java.awt.geom.Arc2D;
javax.swing.JPanel;
public class LogSpiralPanel extends JPanel
{
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
/*
Your code goes here.
1. create the goldenRectangle (you can use getHeight() to
obtain the side size
2. draw the golden rectangle
3. call the recursive helper method "recursiveDraw" which will
draw the spiral
*/
}
/**
Method that recursively draws a logarithmic spiral.
@param x The upper left corner x-coordinate of the golden
rectangle
@param y The upper left corner y-coordinate of the golden
rectangle
@param side the smallest side size of the golden rectangle
@param angle the angle (0, 90, 180 or 270) where the top of the
golden rectangle is located.
For the outermost golden rectangle, the angle is 90.
*/
private void recursiveDraw(Graphics2D g2, double x, double y,
double side, int angle)
{
// we'll do this in the next section. . .
}
private static final double GOLDEN_MEAN = (1 + Math.sqrt(5)) / 2;
}
What is the code of your completed paintComponent method?
7. Now you will complete the code of the recursive helper method recursiveDraw.
To recursively draw the logarithmic spiral, you first need to draw the square. The
square's upper-left corner is at position (x, y), and its side size is side. Then you
need to draw the arc. You can use the method drawArc that has been provided for
you. Then you need to recursively call recursiveDraw to continue drawing the
spiral recursively. Before making the recursive call you need to calculate the new
side size, the new x-coordinate, the new y-coordinate and the new angle. Two
methods calculateNewX and calculateNewY have been provided for you. You
can use these methods to calculate the new x and y coordinate, but you need to
calculate the new side size and the new angle yourself. Remember that the new
side size is the difference between the sizes of the two sides of the current
rectangle. The new angle is given by rotating the current angle 90 degrees in clockwise direction.
public class LogSpiralPanel extends JPanel
{
public void paintComponent(Graphics g)
{
. . .
}
/**
Method that recursively draws a logarithmic spiral.
@param x The upper left corner x-coordinate of the golden
rectangle
@param y The upper left corder y-coordinate of the golden
rectangle
@param side the smallest side size of the golden rectangle
@param angle The angle (0, 90, 180 or 270) where the top
of the
current golden rectangle is located.
For the outermost golden rectangle, the angle is 90.
*/
private void recursiveDraw(Graphics2D g2, double x, double y,
double side, int angle)
{
/* Recursion ending condition: when the side is very small
*/
. . .
/* Draw the current square and arc */
. . .
/* Continue drawing the spiral recursively: calculate the
new side size, calculate the new
(x, y) coordinates and the new angle. Then, call
"recursiveDraw" again. */
. . .
}
/**
Draws the arc of the current iteration.
@param x The upper-left corner x-coordinate of the square
@param y The upper-left corner y-coordinate of the square
@param side The size of the side of the square (or the
arc's radius)
@param angle The angle (0, 90, 180 or 270) where the top
of the current golden rectangle is located.
For the outermost golden rectangle, the angle is 90.
*/
private void drawArc(Graphics2D g2, double x, double y, double
side, int angle)
{
double auxX = x;
double auxY = y;
if (angle == 0 || angle == 270)
auxX = x - side;
if (angle == 270 || angle == 180)
auxY = y - side;
Rectangle2D.Double boundingRectangle =
new Rectangle2D.Double(auxX, auxY, side * 2, side * 2);
Arc2D.Double arc = new Arc2D.Double(boundingRectangle, angle,
90, Arc2D.OPEN);
g2.draw(arc);
}
private double calculateNewX(double x, double angle, double side,
double newSide)
{
if (angle == 0)
x = x + side - newSide;
else if (angle == 90)
x = x + side;
else if (angle == 270)
x = x - newSide;
return x;
}
private double calculateNewY(double y, double angle, double side,
double newSide)
{
if (angle == 0)
y = y + side;
else if (angle == 180)
y = y - newSide;
else if (angle == 270)
y = y + side - newSide;
return y;
}
private static final double GOLDEN_MEAN = (1 + Math.sqrt(5)) / 2;
}
What is the code of your recursiveDraw method?
8. Create a LogSpiralFrame class that will contain the LogSpiralPanel. What is the
code of your class?
9. What is the code of your viewer class?
The Efficiency of Recursion
10. The golden mean, often referred to as the golden ratio, divine proportion, or the
golden number is represented by the Greek letter phi (φ). The value of the golden
mean is (1 + sqrt(5)) / 2 or 1.61803 . . . The golden mean is found in nature and art
and tends to yield the most "aesthetically pleasing" arrangements of objects.
Fibonacci numbers are directly related to the golden mean. The definition of
Fibonacci numbers is
fib(1) = 1
fib(2) = 1
fib(n) = (fib(n-1) + fib(n-2))
After the first two numbers, each of which has the value of 1, the next number in
the Fibonacci sequence is the sum of the two preceding numbers.
Computing ratios of Fibonacci numbers can approximate the value of the golden
mean. The value of.
g(n) = fib(n) / fib(n-1)
approximates the golden mean as n goes to infinity.
These values can be computed recursively as well. Note that
g(n) = (fib(n - 1) + fib(n - 2)) / fib (n - 1)
Simplify this expression so that g(n) is expressed in terms
of g(n - 1).
(a) What is your recursive definition for g(n)?
(b) When does the recursion stop?
11. Write a recursive method that computes the nth iteration of the golden ratio. What
is the code of your method?
12. What is the tenth approximation of the golden ratio?
13. As you learned in the textbook, the recursive computation of fib(n) can be
inefficient. Add trace statements to verify that your method for computing g(n)
does not calculate each number more than once. What is the output of your trace
messages?
Mutual Recursion (and More Efficiency)
14. In one variant of the game of Nim, two players alternately take marbles from a pile.
In each move, a player chooses how many marbles to take. The player must take at
least one but at most half of the marbles. Then the other player takes a turn. The
player who is left with one marble loses.
Clearly, if you start with two marbles, you are going to win. Take one marble, and
your opponent loses right away. We therefore say that 2 is a winning position.
In general, a winning position is a position in which you can force a win. That is,
there is at least one move that leads to a losing position.
Conversely, a losing position is a position that is either an outright loss, or in which
every move leads to a winning position.
Following these definitions, write mutually recursive methods
public class NimCalculator
{
public boolean isWinningPosition(int n)
{
for (int i = 1; i <= n / 2; i++)
. . .
}
public boolean isLosingPosition(int n) { . . . }
}
What is the code for your methods?
15. Run a test program.Which values between 2 and 100 are losing positions?
16. Why does this recursion run so slowly? Add trace messages to find out.
17. You can speed up the methods by remembering for which numbers you have
already determined the answers. Use an array to store known positions.
public class NimCalculator
{
public boolean isWinningPosition(int n) { . . . }
public boolean isLosingPosition(int n) { . . . }
private int[] knownPositions = new int[10000];
}
Here, knownPosition[i] should be 1 if i is known to be a winning position, and 1 if i is known to be a losing position, and 0 if it is not known to be either.
What is the code for your modified isWinningPosition and isLosingPosition
methods?
18. Now run your program again. Just print out the losing positions < 10000
Big Java / Java Concepts Lab 19
Sorting
1. Add a counter to the MergeSorter that counts how many times the algorithm
compares two array elements. Supply a method getCounter to retrieve the
counter. Then run the following experiment. For n = 10000, 20000, . . ., 100000,
prepare an array with descending integer values n, n - 1, n - 2, . . .,3, 2, 1. Pass it to
the MergeSorter, then print out how many comparisons were made.
What results did you get?
2. Implement the bubble sort algorithm.
The bubble sort is so called because it compares adjacent items, "bubbling" the
smaller one up toward the beginning of the list. By comparing all pairs of adjacent
items starting at the end of the list, the smallest item is guaranteed to reach the
beginning of the list at the end of the first pass.
The second pass begins again at the end of the list, ultimately placing the second
smallest item in the second position in the list. During the second pass, there is no
need to compare the first and second items, since the smallest element is
guaranteed to be in the first position.
Bubble sort takes at most n-1 passes for a list of n items. During the first pass, n-1
pairs need to be compared. During the second pass, n-2 pairs need to be compared.
During the ith pass, n-i pairs need to be compared. During the last pass, n-(n-1) or
one pair needs to be compared. If, during any pass, no two adjacent items need to
be interchanged, the list is in order and the sort can terminate. If it continues, no
further interchanges will occur.
A variation on the bubble sort starts each pass at the beginning of the list,
interchanging items as needed so that a larger item "sinks" below a smaller item
following each comparison. Such a sort might be called a "rock sort," but this term
is not in common usage.
What is the code of your BubbleSorter class?
3. Describe the efficiency of the bubble sort algorithm and represent it in Big-Oh
notation.
4. A variation on the bubble sort starts each pass at the beginning of the list,
interchanging items as needed so that a larger item "sinks" below a smaller item
following each comparison. (Such a sort might be called a "rock sort," but this term
is not in common usage.)
Implement this variation. What is the code for your sort method?
Comparable
and Comparator
5. We want to sort a list of cities by name; however, if there are two cities with the
same name, then we use the state name as tie breaker. Implement a City class and
a constructor
public City(String name, String state)
Also supply a toString method--we will need it for testing.
Have your City object implement the Comparable<City> interface.
What is the code of your City class?
6. Write a tester class that populates an ArrayList<City> with cities and then sorts
it. What is the code of your tester class? Remember that you can use
Collections.sort to sort an array list.
7. Now we want to sort lists of cities first by state name, then by city name, without
modifying the implementation of the City class. That means, you cannot redefine
the compareTo method. Instead, define a CityComparator class that implements
the Comparator<City> interface.
public class CityComparator implements Comparator<City>
{
public int compare(City a, City b)
{
. . .
}
}
What is the code of your CityComparator class?
8. Write a tester class that populates an ArrayList<City> with cities and then sorts
it, using a CityComparator. What is the code of your tester class?
Binary Search
9. We will implement a "guess your name" game. The computer will guess your last
name:
This
some
Does
Does
Does
Does
program tries to guess your last name, but you have to give
hints.
your name come before "MYERSCOUGH" in the dictionary? (Y/N) Y
your name come before "ISENBERG" in the dictionary? (Y/N) Y
your name come before "DIMAGGIO" in the dictionary? (Y/N) N
your name come before "GALLUP" in the dictionary? (Y/N) N
. . .
Is your name "HORSTMANN"? (Y/N) Y
Start out with a program that reads all names from the "last names" file at
http://www.census.gov/genealogy/names/. Discard the statistical information. Sort
the names, using Collections.sort.
What is the code for reading all names and sorting them?
10. At the beginning of the search, set low to 0 and high to the maximum index of the
names list. Set mid to the average of low and high, then ask the user if the name
comes before the list entry at index mid. Depending on the answer, update low or
high. If low == high, ask if the name matches.
What is the code for your program?
11. How many entries does your names list have? How many guesses does your
program need to make until it has guessed the user's name or given up?
Big Java / Java Concepts Lab 20
Using Linked Lists
1. Using the "cursor in a word processor" notation from the book, indicate the
contents of the list and the iterator position after each step in the code below.
LinkedList<String> letters = new LinkedList<String>();
ListIterator<String> iterator = letters.listIterator();
iterator.add("A"); iterator.add("C"); iterator.add("D"); iterator =
letters.listIterator(); iterator.next(); iterator.next();
iterator.remove();
Implementing Linked Lists
2. The LinkedList class in the standard Java library has a get(int index) method
that allows you to retrieve arbitrary list elements, just like you can in an
ArrayList. In this lab, we want to analyze why this operation is inefficient.
Add a method
Object get(int index)
to the LinkedList implementation of Chapter 20. What is the code for your
method?
3. What does your method do if index is < 0 or >= the size of the linked list?
4. Write a tester program that adds ten items to a LinkedList and then executes the
loop
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i));
What is the code for your tester program?
5. How many times does the tester program look up the next value of a list node?
How many lookups would it make if there were 100 elements in the list?
6. It is possible to optimize the behavior of the get method in some common cases.
You can cache the last visited position and its Node pointer. Then you can start
from that position instead of the start of the linked list.
public Object get(int index)
{
Node current;
if (lastVisitedPosition > 0 && lastVisitedPosition < index)
{
current = lastVisitedNode;
while (. . .)
current = current.next;
}
else
{
current = first;
while (. . .)
current = current.next;
}
// remember for next time
lastVisitedPosition = index;
lastVisitedNode = current;
. . .
}
Finish the implementation of the method, and test it with the same tester program.
What is the code of the get method?
7. With this modification, how many times does the tester program look up the next
value of a list node?
8. This is an ingenious trick, but it has limitations. If another method mutates the
linked list, then the cached position may no longer be accurate, and the cache
should be invalidated by setting lastVisitedPosition to -1. Which methods of
the LinkedList and LinkedListIterator class need to be modified?
9. The standard library does not use this trick in its implementation of get, but it uses
another optimization: if index is > size() / 2, then the search starts at the end of
the list, not at the beginning. With that optimization, how many lookups of the
next or previous value would the tester program make if it looped through a list
with 100 elements?
Abstract and Concrete Data Types
10. You are assigned to write a program to schedule appointments for a doctor's office.
An appointment is scheduled every half an hour from 8 a.m. to 4 p.m., with no
appointments between 12 p.m. and 1 p.m. Not all times may be scheduled, and
some times may be double-booked. You must be able to delete and add
appointments at anytime. Would you use a linked list or an array to store
appointments? Why?
11. When performing a binary search, is it more appropriate to use an array or a linked
list? Why?
Stacks and Queues
12. A deque is a double-ended stack or a double-ended queue. Items can be inserted or
removed from either end. Write an implementation of a deque of strings using a
LinkedList. No other type of element access should be permitted (e.g. get element
at position i).
public class Deque
{
. . .
public void addFirst(Object str){ . . . }
public Object removeFirst(){ . . . }
public void addLast(Object str){ . . . }
public Object removeLast(){ . . . }
private LinkedList<Object> list;
}
13. Suppose you make your previous deque implementation iterable by modifying it as
follows:
public class Deque implements Iterable<Object>
{
. . .
public Iterator<Object> iterator()
{
return list.iterator();
}
private LinkedList<Object> list;
}
Now you can iterate through the deque using the "for each" loop. Adding this
functionality is very useful because it allows us to iterate through the elements of
the queue and print them.
Write a test program that adds elements to a deque and then prints them out with a
"for each" loop. What is your test program?
14. The problem is that by returning an iterator, we would be allowing an illegal
operation to the deque: to be able remove an element at an arbitrary position, by
calling iterator.remove().
Write a tester program that shows that if you change your queue implementation as
suggested above, you can now remove an element in the middle of the list.
15. You can solve the problem by disabling the remove() method for your Deque
iterator You can do that by creating your own iterator class which just calls the
methods of the list iterator, except for the remove method. If another class calls the
iterator's remove method, the method should not perform the remove operation;
instead, it should throw an UnsupportedOperationException.
Part of the code of the class has been provided for you:
public class Deque implements Iterable<Object>
{
public Iterator<Object> iterator() { return new DequeIterator(); }
private class DequeIterator implements Iterator<Object>
{
public DequeIterator() { . . . }
public boolean hasNext() { . . . }
public Object next() { . . . }
public void remove() { . . . }
private Iterator<Object> iterator;
}
...
}
What is the code of your modified ListQueue class?
16. Use the tester program you created in problem 14. What happens when you try to
remove an element using the iterator's remove()?
17. A couple has a monthly surplus of $300 that is set aside in an account for
discretionary spending. The account balance was $0 in January. In April, the
couple decided to purchase a new couch that cost $1600. In May they decided to
purchase a weaving loom that cost $2000. In August, they decided to purchase a
laptop computer for $1,100. In September, they decided to purchase a trip to Italy
for $4,000. In December, they decided to purchase a season pass for the local
cross-country ski resort for $200.
Items are purchased when there is money available. Unpurchased items remain in
the queue until sufficient funds become available. This way, the items are
purchased in the order that they are requested.
Write a program to simulate the spending and savings of this couple. Allow a user
to enter the amount of discretionary money that is set aside each month. Also allow
the user to enter items to be purchased each month.
What is the code for your program?
18. With the data from the preceding problem,
1. What is the largest surplus accumulated in the special account for
discretionary spending?
2. What is the largest deficiency for items for which there are insufficient
funds?
Modify your program to supply this information and give the results.
Big Java / Java Concepts Lab 21
Sets and Maps
1. Consider the following line of code:
Set names = new HashSet();
Why is the variable names of type Set rather than type HashSet?
2. Unlike the ListIterator interface, the Iterator interface for a set cannot add
an item to a specified position. Is there a reason for this? If so, what is it?
3. The Iterator interface contains a next method. Why does the interface not
contain a previous method?
4. For each of the following problems, indicate whether it would be more appropriate
to use a HashSet or a HashMap, and explain your reasoning:
1. A program that keeps track of bank account information (name, account number,
account type, balance)
2. A phonebook program that stores your friends' names and phone numbers
3. A program to inventory the contents of your refrigerator
4. A program that stores a list of your favorite fruits
5. A program that stores a list of the favorite fruits of all the students in your class.
5. Suppose you write a program to keep track of the hometowns of all the students in
your class using a HashMap. What values would you use for the key set? What
values would you use for the value set?
6. The static method TimeZone.getAvailableIDs returns an array of time zone ID
strings, such as America/Los_Angeles or Asia/Bankgok. Once you have an ID,
you can get the time zone by calling the static method TimeZone.getTimezone.
Finally, to find the time at a given time zone, call
DateFormat timeFormatter = DateFormat.getTimeInstance();
timeFormatter.setTimeZone(zone);
Date now = new Date();
System.out.println(timeFormatter.format(now));
Unfortunately, there is no fast method for finding the time zone for
"Los_Angeles". We want to speed up this search by using a Map<String,
TimeZone>.
Write a program that calls getAvailableIDs, strips out the city names (by
discarding the Continent/ prefix and turning underscores into spaces), gets the
TimeZone objects, and puts the (city name, time zone) pairs into a map.
To verify that your map is set up correctly, print out the first ten entries.
What is the code for your program?
7. What does your program print?
8. Now enhance your program so that users can enter city names. Look up the time
zone for the city and print out the local time, or tell the user if you can't find a
matching city.
City: Los Angeles
Local time: 06:26:09
City: Berlin
Local time: 15:27:12
City: Fargo
Local time: not available
City: Quit
Bye
What is the code for your program?
Hashing
9. Create an Employee class. The class contains the id (of type long), name, phone
number and job title of the employee. Implement the methods:
public boolean equals(Object other)
public int hashCode()
10. Write a test program that stores a set of employees in a HashSet<Employee> and
prints out the elements in the set. Try adding the same employee twice. What is the
code of your test program?
11. How can you simplify the equals and hashCode methods if you know that
employees are uniquely determined by their ID?
Binary Search Trees
12. Write a program that builds up the following binary search tree and prints its
contents.
5
/
\
3
/
8
\
1
/
4
\
\
6
10
\
2
7
/
9
What is the code for your program?
13. In this exercise, we will add an iterator to the binary search tree class in the text
book. We want to be able to execute code such as
BinarySearchTree tree = new BinarySearchTree();
// add elements
Iterator iter = tree.iterator();
while (iter.hasNext())
do something with iter.next();
The iterator should visit the tree elements in sorted order.
Here is a naive attempt at the iterator:
public class BinarySearchTree
{
. . .
public Iterator iterator() { return new BSTIterator(); }
private class BSTIterator implements Iterator
{
public BSTIterator() { current = root; }
public boolean hasNext() { return current != null; }
public Object next()
{
Object r = current.data;
if (current.left != null) current = current.left;
else current = current.right;
return r;
}
14. The simplistic implementation can't back up when it reaches a leaf. Unfortunately,
our Node objects don't have a pointer to the parent. Therefore, we need to store a
stack of partially explored nodes. When reaching a leaf, pop off the top of the stack
and continue the search at that node.
private class BSTIterator implements Iterator
{
. . .
private Node current;
private Stack<Node> partiallyExplored;
}
Draw pictures of the state of this iterator for each traversal step in the tree of
problem 11.
13. Now implement the iterator class. What is the code for your implementation?
14. Add an iterator to the program that you wrote in problem 12. What is the code for
your test program?
Tree Sets
15. Write a program that uses a tree set to store employees. Ask the user to enter
employee information, add each employee to the three set. When the user is done,
print the elements of the tree set. You can modify the program you created in
problem 10.
16. Run both implementations of the program (the one that uses a hash set and the one
that uses a tree set) and insert information about the employees Brown, Smith and
Johnson (in that order). What is the output of both programs?
Heaps
17. A min-heap is an almost complete tree in which the values of all nodes are at most
as large as those of their descendants. A max-heap is the opposite of a min-heap.
The largest element is stored in the root of a max-heap.
Turn the MinHeap class in the book into a MaxHeap class. What is the code?
18. Write a tester class that tests your MaxHeap.
What is the code?
19. For convenience, the MinHeap and MaxHeap class leave the 0 element of the array
empty. Then the child nodes of the node with index i have index 2 · i and 2 · i + 1 ,
and the parent node of the node with index i has index i / 2.
Change your implementation so that the 0 entry is not wasted. (Hint: Look at the
HeapSorter class of your text book.) Run your test program again to verify that
your changed implementation works correctly.
What changes did you need to make?
Big Java / Java Concepts Lab 22
Implementing Generic Classes
1. Modify the class Pair<T, S> so that it implements Comparable<Pair<T, S>>. To
compare a pair with another, you compare the first element (using compareTo). If
they are equal, you should compare the second elements and return the result of
their comparison. If the first elements are not equal, the compareTo method returns
the result of first.compareTo(other.first).
2. Create a PairTester class that tests the class you just created. Create a new
TreeSet and add pairs to it. The pairs should consist of people names (last name,
first name). At the end, iterate through the set and print its contents. If your Pair
class was correctly implemented, the output should be displayed in alphabetic order
(because a TreeSet implements a set using a binary search tree). Be sure to try a
few pairs with the same last name.
3. What happens if you try to add a Pair<String, Integer> to the set? What
happens if your try to create a Pair<String, Rectangle>? Try it out and explain.
4. Turn the MinHeap class in Section 21.9 of your textbook into a generic class. The
bound of the type variable should extend the generic Comparable interface:
public class MinHeap<E extends Comparable>
You need not understand the inner workings of the MinHeap class in order to carry
out this exercise. Simply change methods such as
public Comparable peek()
into
public E peek()
so that the user of the generic class need not apply any casts. Be sure to change the
type of the elements instance field to ArrayList<E>.
What is the code for your modified class?
5. A heap (in this case, a min-heap) can be used as a priority queue. Modify the
following program so that it uses your generic MinHeap class and it uses
Pair<Integer, String> instead of the class WorkOrder.
/**
This program demonstrates the use of a heap as a priority
queue.
*/
public class HeapTester
{
public static void main(String[] args)
{
MinHeap q = new MinHeap();
q.add(new WorkOrder(3, "Shampoo carpets"));
q.add(new WorkOrder(7, "Empty trash"));
q.add(new WorkOrder(8, "Water plants"));
q.add(new WorkOrder(10, "Remove pencil sharpener
shavings"));
q.add(new WorkOrder(6, "Replace light bulb"));
q.add(new WorkOrder(1, "Fix broken sink"));
q.add(new WorkOrder(9, "Clean coffee maker"));
q.add(new WorkOrder(2, "Order cleaning supplies"));
while (q.size() > 0)
System.out.println(q.remove());
}
}
6. In the previous exercise, could you have replaced the WorkOrder class with
Pair<String, Integer>? (e.g. q.add(new Pair<String, Integer>("Shampoo
carpets", 3));). Explain your answer.
Generic Methods
7. Add a generic getRandomElement method to the ArrayUtil class of your
textbook that returns a random element from an array of type E[].
(Use a static random number generator, and generate a random integer between 0
and a.length - 1.)
What is the code for your generic method?
8. Add a generic getRandomPair method to the ArrayUtil class. It should return a
randomly chosen pair, with the first index less than the second index. For example,
if called with the array ["A" "B" "C" "D"], then a pair ("A", "B"), ("A",
"C"), ("A", "D"), ("B", "C"), ("B", "D"), ("C", "D") is chosen with equal
probability.
What is the code for your generic method?
10. Write a tester class that tests the static methods you created. What is the code for
your tester class?
Constraining Type Variables
11. In the ArrayUtil class, write generic methods
void saveToFile(E[] a, String filename) throws IOException
E[] loadFromFile(String filename) throws IOException,
ClassNotFoundException
The first method saves the elements of the given array to an ObjectOutputStream.
The second method loads an array of objects from an ObjectInputStream.
When writing the type variable of the method, you should take into consideration
that the elements of the array must implement the Serializable interface.
12. Write a tester program for your previous class. Create an array of strings and add
several strings to it. Save the list to a file, afterwards read them from the file and
display them on screen.
13. What happens if you don't supply the Serializable bound for the elements of the
array list?
First change your tester program so that the elements of the array are of type
Pair<String, String>. Try it out and explain.
Then, change your class to remove the Serializable bound, use your modified
tester program and try it out. Explain.
Overcoming Limitations of Java Generics
14. Generic classes and methods were added to Java several years after the language
became successful. The language designers decided to use the type erasure
mechanism because it makes it easy to interface generic code with legacy
programs. As a result, you may run into some programming restrictions when you
write generic code.
For example, you cannot construct an array of a generic type. The following
method, which tries to grow an array, would be wrong:
public static <E> E[] grow(E[] a)
{
E[] newArray = new E[2 * a.length + 1]; // ERROR
for (int i = 0; i < a.length; i++)
newArray[i] = a[i];
return newArray;
}
To see why this is a problem, carry out the type erasure process, as if you were the
compiler.
What would be the result?
15. A tempting workaround would be to create an array of objects, like this:
public static <E> E[] grow(E[] a)
{
E[] newArray = (E[]) new Object[2 * a.length]; // ERROR
for (int i = 0; i < a.length; i++)
newArray[i] = a[i];
return newArray;
}
Try out this "solution". What happens when you call
String[] original = {"Hello", "World"};
String[] grown = ArrayUtil.grow(original);
16. To solve this problem, you need to find out the type of the array a and make a new
array of the same type.
You can get the type of the components of a by calling
Class cl = a.getClass().getComponentType();
The object cl is a descriptor for the component type. For
String[] array, then cl describes the String type.
example, when a is a
Now use the newInstance method of the java.lang.reflect.Array class to
make a new array of the type cl. You still need to cast the result as E[] (and you
will still get a warning), but now you are no longer lying.
What is the code for your modified grow method?
17. Write a tester class for the grow method.
What is the code of your tester class?
Big Java Lab 23
Running Threads
1. Write a program to simulate a simple traffic light at an intersection of two roads.
It will be easiest to view the example as four one-way roads, since cars can approach and
pass through the intersection from four directions. Assign each road a number from 1 to
4.
Each time a car is at the intersection, request that the traffic light turn green. Implement a
traffic light object with a turnGreen(int roadNumber) method. When a car is at the
intersection it will call this method and pass its number. If road number 1 calls the
turnGreen method, the method should print out:
Light turned green by road 1
Waiting for road 1 car to clear intersection
10 9 8 7 6 5 4 3 2 1 0
Use a loop to print a countdown of the waiting period from 10 to 0.
What is the code of your TrafficLight class.
Big Java Lab 24
Sockets
1. Write a program that uses a socket to retrieve the correct time from a timeserver using the
DAYTIME protocol.
There are many servers on the Internet that provide a time service. The National Institute
of Standards and Technology http://www.bldrdoc.gov/ maintains several timeservers that
allow users to synchronize a clock. One protocol used is the Daytime protocol. The
Daytime protocol is a simple protocol. The user connects on port 13 and sends a newline
character. The server responds by sending back an ASCII string and then disconnects.
The time string from the NIST servers is in the following format:
JJJJJ YR-MO-DA HH:MM:SS TT L H msADV UTC(NIST) *
In this simple exercise, we are concerned only with the first half of the string.
JJJJJ
represents the last five digits of the Julian date. You can ignore this value.
YR-MO-DA YR
represents the last two digits of the year, MO represents the month and DA,
the current day.
HH:MM:SS
is the time in hours (HH), minutes (MM) and seconds (SS). This is sent in
Coordinated Universal time.
You need to add an offset to correct the time to your time zone.
Write a program that connects to three of the NIST servers listed below, using the
Daytime protocol. Parse the return string and create a Date object set to the return string's
time. Print out the return strings and your Date objects. Use a SimpleDateFormat to
format your date. Make sure you adjust the time to your correct time zone. You should
read the Java API documentation to obtain more information on the SimpleDateFormat
class. Basically you will need to use the class to parse the string (or substring of) returned
by the server. For example, the following formatter is able to format a string of the form
"05-02-25 17:30:49 UTP", by using its parse method:
SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss
z");
After obtaining a Date object using formatter.parse, you can format it to your local
time using the format method of the DateFormat class:
DateFormat localFormatter = DateFormat.getDateTimeInstance();
NIST Timeservers
Name
Location
time-a.nist.gov
NIST, Gaithersburg, Maryland
time-b.nist.gov
NIST, Gaithersburg, Maryland
time-a.timefreq.bldrdoc.gov
NIST, Boulder, Colorado
time-b.timefreq.bldrdoc.gov
NIST, Boulder, Colorado
time-c.timefreq.bldrdoc.gov
NIST, Boulder, Colorado
utcnist.colorado.edu
University of Colorado, Boulder
time.nist.gov
NCAR, Boulder, Colorado
time-nw.nist.gov
Microsoft, Redmond, Washington
nist1.datum.com
Datum, San Jose, California
nist1.dc.glassey.com
Abovenet, Virginia
nist1.ny.glassey.com
Abovenet, New York City
nist1.sj.glassey.com
Abovenet, San Jose, California
nist1.aol-ca.truetime.com
TrueTime, AOL facility, Sunnyvale, California
nist1.aol-va.truetime.com
TrueTime, AOL facility, Virginia
What is the code of your program?
2. Modify your previous program so that it uses the TIME protocol instead of the
DAYTIME protocol. To use the Time protocol, a user connects on port 37 and sends a
newline character. The server responds by returning a 32-bit unformatted binary number
that represents the time in UTC seconds since January 1, 1900.
Hints:
Unlike the C language, Java does not have an unsigned data type to represent an
unsigned 32-bit binary number. An int in Java represents a 32-bit signed binary number.
Usually a larger type, in this case a long, is used to store an unsigned int. The time server
sends four bytes that represent an unsigned int, which you will have to store in a long.
Instead of using a scanner, you will need to read an array of bytes using the input stream
directly:
byte[] b = new byte[4];
instream.read(b);
Then, you will need to convert the byte array to a long. You can use the following
method for the purpose:
public static
{
long l = 0;
l |= b[0] &
l <<= 8;
l |= b[1] &
l <<= 8;
l |= b[2] &
l <<= 8;
l |= b[3] &
return l;
}
final long unsignedIntToLong(byte[] b)
0xFF;
0xFF;
0xFF;
0xFF;
Java stores dates as the number of milliseconds since January 1, 1970. The Time
protocol returns the number of seconds since January 1, 1900. To compute the
difference, create a GregorianCalendar object that represents 01/01/1970 and a
GregorianCalendar object that represents 01/01/1900. Call getTimeInMillis() on
each to retrieve the milliseconds. Then subtract to find the difference. Convert the
difference to seconds and add it to the return value. Convert the corrected return value to
milliseconds to create your Date object.
Client/Server
3. Create a server application that uses the following protocol:
Client Request
Server Response
Meaning
HELLO
greeting
ECHO n
n
COUNT
Sends a greeting
Echoes n back to the client
The number of ECHO requests Returns a count of the number of ECHO
requests by client
QUIT
goodbye
Prints a goodbye and quits the connection
You may choose the greeting and goodbye messages to send. In this exercise you will create
three classes:
SimpleProtocolService
SimpleProtocolServer
SimpleProtocolClient
The server should accept multiple simultaneous connections with different clients.
What is the code of your SimpleProtocolService class? Part of the code of the class has been
provided for you:
public class SimpleProtocolService implements Runnable
{
public SimpleProtocolService(Socket aSocket) { . . . }
public void run()
{
try
{
try
{
in = new Scanner(s.getInputStream());
out = new PrintWriter(s.getOutputStream());
doService();
}
finally
{
s.close();
}
}
catch (IOException exception)
{
exception.printStackTrace();
}
}
public void doService() throws IOException { . . . }
public void executeCommand(String command) { . . . }
. . .
...
}
4. To support multiple simultaneous connections, construct a new thread to communicate
with each client. What is the code of your SimpleProtocolServer class?
5. Write a client that connects to the server, sends several commands and disconnects. What
is the code of your SimpleProtocolClient class?
URL Connections
6. Write a program that gets a weather report for your state. The URL is
http://iwin.nws.noaa.gov/iwin/xy/hourly.html
where xy is a 2-letter state abbreviation such as ca or ny.
Your program should get the data from the web site and strip out all HTML formatting,
printing just the raw weather report.
7. What is the output of your program if the URL points to an invalid location? (for
example, http://iwin.nws.noaa.gov/iwin/ev/hourly.html)
Tic-tac-toe
8. In this section, we will create a server application that allows two players to play tic-tactoe against each other.
Design and implement a protocol to play tic-tac-toe.




A player can connect, give the player name, and wait for an opponent.
When two opponents have connected, the server picks one of them to start
playing.
The active player must be able to transmit a move to the server. The server checks
that the move is valid. If the last move finishes the game, the server pronounces
the winner.
The server notifies both players of the new board position, and, if the game is not
yet over, asks the opponent to play.
Simply number the rows and columns and communicate moves with the row and column
numbers.
What are the client requests and server responses in your protocol?
9. What is the code of your TicTacToeServer class?
10. What is the code of your TicTacToeServer class?
11. What is the code of your TicTacToeClient class?
Big Java Lab 25
SQL
1. Design a set of database tables for a pizza restaurant.
The restaurant stores the names, addresses, and phone numbers of its home delivery
customers. All the current and previous orders for each customer are stored in the
database. An order includes one or more pizzas. A pizza has size, crust type, one or more
toppings.
The price of a pizza is the sum of the base price ($10 for a small pizza, $13 for a medium,
and $16 for a large pizza), plus the sum of the topping prices. The crust type doesn't
affect the price.
List the SQL code creating the tables.
2. Write SQL statements to populate your tables with data.
3. Give a SQL query that lists all pizza toppings for your pizza restaurant database.
4. Give an SQL query to find if there is a customer named 'John Smith' in the database.
Give an SQL query to find the customer code (or id) for the customer named 'John
Smith'.
5. Give a SQL query that describes a particular order for a particular client, for example,
order with order code '6' for client '1'.
6. How can you calculate the total of an order?
JDBC
7. Write a Java program to implement your pizza restaurant database.
The restaurant stores the names, addresses and phone numbers of its customers. All the
current and previous orders for each customer are stored in the database. An order
includes one or more pizzas. A pizza has size, crust type and one or more toppings.
The price of a pizza is the sum of the base price ($10 for a small pizza, $13 for a medium,
and $16 for a large pizza), plus the sum of the topping prices. The crust type doesn't
affect the price.
Using the tables you created and populated with data, write a PizzaOrderingSystem
class with a method
public void acceptOrder()
that asks for the customer information and order, and stores the information in the
database. You may additional helper classes.
What is the code of your PizzaOrderingSystem class?
8. Did you use helper classes? If so, what is their code?
9. What is the code of your tester program?
10. To run your program you need a database properties file. What is the content of your
database.properties file?
11. You are the store manager and want to give a special prize to your best customer. Give an
SQL query to find out what customer has the greatest number of orders in the system.
Big Java Lab 26
Parsing XML Documents
1. Consider the following XML file that describes a pizza:
<pizza>
<name>BBQ Chicken</name>
<description>
<crust>thin</crust>
<vegetable>red onion</vegetable>
<vegetable>cilantro</vegetable>
Make a similar XML file that describes your favorite pizza.
2. Write a program that can read XML files for describing a pizza, in the format of the
preceding exercise.
Read the information in the file and create an instance of a class Pizza and then display
it on screen, including the total pizza price. You can use the Pizza class and helper
classes that you created in lab 17.
What is the code of your parser class?
3. What is the code of your tester class?
4.
Creating XML Documents
Write a program to create a pizza restaurant menu stored as an XML file. Read in several
XML files describing pizzas, in the same format as before. Make a Menu object that
contains an ArrayList<Item>. Each item contains a pizza and a price.
Your program should then produce an XML document with a <menu> root element
describing the menu:
<menu>
<item>
<pizza>
. . .
</pizza>
<price>...</price>
</item>
<item>
<pizza>
. . .
</pizza>
<price>...</price>
</item>
</menu>
What is the code of your builder class?
5. What is the code of your tester class?
Document Type Definitions (DTDs)
6. Design a document type definition (DTD) that describes a pizza.
Include a name and description, including crust type, toppings, and sauce.
7. Write a program that can read and validate XML files for describing a pizza.
Modify your existing program to read an XML file containing a pizza description, using
a DTD for validation.
How does your parser class change?
8. What happens if you use the following as your pizza.xml file?
<?xml version="1.0"?>
<!DOCTYPE pizza SYSTEM "pizza.dtd">
<pizza>
<name>BBQ Chicken</name>
<description>
<crust>thin</crust>
<size>medium</size>
<sauce>barbecue</sauce>
<cheese>gouda</cheese>
<cheese>mozzarella</cheese>
<toppings>
<topping>chicken</topping>
<topping>red onion</topping>
<topping>cilantro</topping>
</toppings>
</description>
<price currency="USD">16</price>
</pizza>
Big Java Lab 27
Warming Up
1.
Create a JSF page that uses a bean to display a random number between 1000 and 9999.
Use the following format:
Today's lucky number is 1729.
What is the code of your bean class?
2.
What are the contents of your index.jsp file? Note: your file can have a different name.
3.
What are the contents of your web.xml file?
4.
What are the contents of your faces-config.xml file?
5.
Describe the directory structure of your application.
A Simple JSF Program
6.
Create a JSP page that uses a JavaBean to display a random "fortune."
Create a list of ten fortunes. When a user opens the page, display a random fortune.
Sample output:
__________________________________________________
The Virtual Fortune Cookie
Your fortune: A short stranger will soon enter your life.
__________________________________________________
What is the code of your bean class(es)?
7.
What are the contents of your *.jsp file(s)?
Interacting with the User
8.
Create a JSF page that allows a user to enter a category for the fortune that they want to
have displayed. Categories might include




Love
Money
Food
Computers
The program displays a fortune that matches the category that the user selected.
Sample output:
__________________________________________________
The Virtual Fortune Cookie
Your fortune: That wasn't chicken you just ate.
__________________________________________________
What is the code of your bean class(es)?
Error Checking and Navigation
10.
Create a JSF page that allows a user to enter a category for the fortune that they want to
have displayed. Use a text field for the category.
If the user entered an unknown category, show an appropriate message. If the user
entered a known category, show a fortune cookie. Both pages should have a "Back"
button that returns to the original page.
What is the code of your bean class(es)?
11.
What are the contents of your *.jsp file(s)?
12.
In what file did you include your navigation rules? How did you define them?
Database Connectivity
13.
For a more robust program, we want to store the fortunes and their categories in a
database.
Modify the bean code so that it looks up fortunes in a database table.
What is the code of your bean class(es)? (You should not modify the JSF pages.)
14.
Give a SQL script that populates the database table.
15.
What error message do you get when a user connects to your JSF application when the
database server is not running?
Download