This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Labs

1-Day In-Class Assignments

1 - Two-Dimensional Arrays Lab

Two di-men., too dimensional to flatten…

The goal of this lab is to gain experience working with two-dimensional arrays.

Instructions

  1. Create a new Eclipse project. Download and import the files Array2D.java and Array2DTest.java.
  2. Complete the unfinished methods in Array2D.java according to the provided JavaDoc comments.
  3. Once all of your methods are implemented and tested, submit your finished work to Gradescope .

Notice that the methods in Array2D.java use a return value of Double.NaN to indicate an error condition. Typically, it would make more sense to design these methods to throw exceptions.

2 - Generics Lab

You have been using generics for some time… it’s time to create your own classes with generic parameters…

Why?

You have been using generics for some time; whenever you make an ArrayList where T is some type, type T is a generic type. You also need to know how to create your own classes with generic parameters. This lab is for practicing this skill.

Success Criteria

Be able to write a class with a generic parameter.

Design

You know what sets are from grade school (and also from reviewing them in your discrete math course). Like lists (for example, ArrayLists), sets are very convenient object containers to have around. There are many ways to implement sets. One way that works well for sets drawn from a small universe (for example, sets that contain various collections of twenty or thirty strings, or sets of enumeration values) is to use arrays to keep track of their contents.

Suppose we have some small collection of values v0, v1, … vn-1 of type T. Call this our universe. Suppose we record these values in an array of type T (called universe, of course), so that v0 is stored at universe[0], v1 at universe[1], and so forth up to vn-1 stored at universe[n-1]. Suppose we also have a boolean array contains of size n. We can represent any set of elements from the universe by setting to true the elements of contains that correspond to the values in the set, and all other elements of contains to false. For example, the set {v1, v5, v12} can be represented by the a contains array with contains[1] == contains[5] == contains[12] == true, and all other elements of contains set to false. This is the idea behind our implementation of an ArraySet.

UML Diagram

Consider the UML diagram below.

classDiagram
class ArraySet~T~ {
  -universe : T[*]
  -contains : boolean[*]
  -int size
  +ArraySet(elements T[*])
  +add(value T) boolean
  +remove(value T)
  +contains(value T) boolean
  +size() int
  +clear()
  +equals(otherSet ArraySet~T~) boolean
}

This class has a generic parameter T, which in UML is typically represented in a dashed box at the upper-right corner of the class symbol. However in this case it is represented beside the class name within angle brackets. Instances of this class are sets of values of a universe of values of type T, as just explained. The count attribute keeps track of how many elements are in the set. Besides the diagram, this class has the following specifications.

Specifications

ArraySet(T[] elements) — This constructor accepts an array of values in the universe and makes an empty set of those values. It copies the values from the elements array into a newly created universe array.

boolean add(T value) — This method adds value to the set, provided it is in universe. If value is in universe, it returns true; otherwise it returns false. Note that adding a value to a set that already contains it does nothing (in particular, it does not alter the size of the set).

void remove(T value) — This method removes value from the set, if it is there; otherwise it does nothing. Note that values outside the universe cannot be in the set, so if such a value is passed to this method, the method does nothing.

boolean contains(T value) — This is the membership method; it returns true just in the case that value is in the set.

int size() — This method returns count.

void clear() — This method makes the set empty.

boolean equals(ArraySet<T> other) — This method return true iff otherSet has the same size and contains the same elements as this set.

Plan

  1. Open Eclipse and make a new project. Download the ZArraySetTest.java class and place it in the default package.
  2. Look over the tests in ZArrayTest.java class to see how the ArraySet class can be used if you are still a little puzzled by how it is supposed to behave.
  3. Create the ArraySet class. Start implementing it in a test-driven development manner. You may find it useful to comment out a lot of the tests in ZArraySetTest.java class until you are ready to implement the code for them (just so you get green bars as you go along). Remember that you can comment out blocks of code in Java using the /* and */ comment delimiters (or highlight several lines and press ctrl + / to toggle single-line comments in most IDES, macOS crew: you typically have to use cmd where the rest of the world uses ctrl).
  4. When you finish, show your successful complete test run to the instructor. If you cannot finish before the end of the class, show what you have got.
  5. If you finish early you might write the following methods (along with tests for them). boolean isSubset(ArraySet<T> otherSet) — returns true iff every element of this set is also a member of the otherSet. ArraySet<T> complement() returns a new ArraySet<T> with the same universe as this set, containing all the values of the universe that are not in this set.

Submitting

Submit your completed file to Gradescope. You may submit as many times as you like.

Acknowledgements

This lab was originally authored by Dr. Chris Fox.

3 - Collections Lab

Introduction

Your goal in this lab is to complete the unfinished methods: CollectionExercises.java

The Gradescope JUnit tests are provided for your convenience: CollectionExercisesTest.java

For each method, you should first take a minute to think about the problem in order to select an appropriate collection type (or types) to use in your solution. The following documentation might be helpful.

You should take full advantage of the functionality provided by the collection classes to make your solutions as concise and efficient as possible. For example, the Collection interface provides an addAll method that makes it possible to add all of the elements of one collection to another using a single method call. Where appropriate, you should use that method rather than creating a loop that repeatedly calls the add method.

Your solutions for these exercises must satisfy the following requirements:

  • You may not use indexed for loops. Use only for-each loops or iterators, as appropriate.
  • None of your methods may include nested loops. Nested loops generally take a long time to iterate over large collections. (You will look at this more formally in CS 240).

Submitting

Submit your completed file to Gradescope. You may submit as many times as you like.

4 - Recursive Structures Lab

Introduction

The goal of this lab is to practice using recursion to interact with recursively structured data. One example of a recursively structured collection is the file system of a computer. A file system is made up of directories, each of which may contain additional directories, and so forth.

Please watch this 6-minute video by Gayle Laakmann McDowell :

Source Files

The following files are provided:

  1. DirectorySearcher.java – This (unfinished) class is responsible for recursively traversing a directory tree starting from a designated directory.
  2. DirectoryDriver.java – This is a driver class for executing the methods provided by DirectorySearcher. As currently written, the main method uses a DirectorySearcher to list the contents of the current directory.

Instructions

  1. Download and test the two files above. Make sure you understand how the existing code works.
    • if you run it as it is when you first download it, you should see something like:
      bin	(Directory)
      .classpath
      .settings	(Directory)
      .project
      src	(Directory)
      
  2. Complete the listDirectories (plural) method of the DirectorySearcher class. Test your method by modifying the driver so that it calls this method instead of listDirectory (singular).
    • Your solution should print a "/" after each directory name and indent the files under each directory. For example,
      1. if the starting path is ".", the output might look like this:
        ./
            bin/
                DirectorySearcher.class
                DirectoryDriver.class
            .classpath
            .settings/
                org.eclipse.jdt.core.prefs
                org.eclipse.core.resources.prefs
            .project
            src/
                DirectorySearcher.java
                DirectoryDriver.java
        
      2. if the starting path is "../PA2", the output might look like this:
        PA2/
            bin/
                io/
                    FileProcessor.class
                    CSVFileProcessor.class
                    FileIdentifier.class
                    CSVRepresentable.class
                testing/
                    VIPAccountTest.class
                    FieldIdentifierTest.class
                    AccountTest.class
                    CSVFileProcessorTest.class
                .gitignore
                membership/
                    VIPAccount.class
                    Account.class
            .classpath
            .project
            src/
                io/
                    FileIdentifier.java
                    CSVFileProcessor.java
                    CSVRepresentable.java
                    FileProcessor.java
                testing/
                    FieldIdentifierTest.java
                    AccountTest.java
                    CSVFileProcessorTest.java
                    VIPAccountTest.java
                membership/
                    VIPAccount.java
                    Account.java
        
  3. Complete the searchDirectories method of the DirectorySearcher class. Test your method by modifying the driver; search for different patterns to make sure it works.
    • Your solution should print the path to each file that is found. (Just print the File object itself, rather than calling getName.) For example, if the search string is "nt", the output might look like this:
      ../PA2/bin/io/FileIdentifier.class
      ../PA2/bin/io/CSVRepresentable.class
      ../PA2/bin/testing/VIPAccountTest.class
      ../PA2/bin/testing/FieldIdentifierTest.class
      ../PA2/bin/testing/AccountTest.class
      ../PA2/bin/membership/VIPAccount.class
      ../PA2/bin/membership/Account.class
      ../PA2/src/io/FileIdentifier.java
      ../PA2/src/io/CSVRepresentable.java
      ../PA2/src/testing/FieldIdentifierTest.java
      ../PA2/src/testing/AccountTest.java
      ../PA2/src/testing/VIPAccountTest.java
      ../PA2/src/membership/VIPAccount.java
      ../PA2/src/membership/Account.java
      
    • while if you searched for empty string "", the output might be:
      ../PA2
      ../PA2/bin
      ../PA2/bin/io
      ../PA2/bin/io/FileProcessor.class
      ../PA2/bin/io/CSVFileProcessor.class
      ../PA2/bin/io/FileIdentifier.class
      ../PA2/bin/io/CSVRepresentable.class
      ../PA2/bin/testing
      ../PA2/bin/testing/VIPAccountTest.class
      ../PA2/bin/testing/FieldIdentifierTest.class
      ../PA2/bin/testing/AccountTest.class
      ../PA2/bin/testing/CSVFileProcessorTest.class
      ../PA2/bin/.gitignore
      ../PA2/bin/membership
      ../PA2/bin/membership/VIPAccount.class
      ../PA2/bin/membership/Account.class
      ../PA2/.classpath
      ../PA2/.project
      ../PA2/src
      ../PA2/src/io
      ../PA2/src/io/FileIdentifier.java
      ../PA2/src/io/CSVFileProcessor.java
      ../PA2/src/io/CSVRepresentable.java
      ../PA2/src/io/FileProcessor.java
      ../PA2/src/testing
      ../PA2/src/testing/FieldIdentifierTest.java
      ../PA2/src/testing/AccountTest.java
      ../PA2/src/testing/CSVFileProcessorTest.java
      ../PA2/src/testing/VIPAccountTest.java
      ../PA2/src/membership
      ../PA2/src/membership/VIPAccount.java
      ../PA2/src/membership/Account.java
      
  4. Submit your completed DirectorySearcher.java file via GradeScope.

5 - Interfaces Lab

Polymorphism in Java via Interfaces.

Introduction

Your goal for this assignment is to modify the Bob’s simulation in two ways: by adding a SortedAisle class, and by making it possible for the user to select the aisle type at run time.

Instructions

Interface

Download the following files:

Create a new class SortedAisle that extends Aisle. Your new class should override the addCustomer method so that every time a new customer is added, the entire list of customers is sorted. This way, the customer with the fewest items is always moved to the front. This type of aisle will model the effect of friendly customers that let other customers “cut” if they have fewer items.

  1. Implement the constructor. It should be only one line of code.
  2. In Aisle.java, make the line attribute visible to SortedAisle. (Hint: Don’t make line private to Aisle. But don’t make it public either.
  3. In SortedAisle.java, override the addCustomer method so that every time a new customer is added, the line of customers is sorted.
  4. Use the Collections.sort method to sort your ArrayList. Since this method only works when the items in the list implement the Comparable interface, you will also need to modify the Customer class to implement Comparable.

Comparable is a generic interface. This means you can use it like this:

public class MyClass implements Comparable<MyClass>

or like this (not recommended):

public class MyClass implements Comparable

In the former class your compareTo method must take an argument of type MyClass in the latter it must take an argument of type Object.

Once you have completed your SortedAisle class modify MartSimulation so that it uses SortedAisles instead of LimitedAisles. (Simply find and replace LimitedAisle with SortedAisle.)

  • Notice the compiler error when calling getLeftStore. That method was added to LimitedAisle to get the number of customers who left the store. SortedAisle doesn’t have such a method.
  • Implement a new getLeftStore method in Aisle that simply returns 0. (By default, no customers leave the store.) SortedAisle will inherit that method, and LimitedAisle will override it.

Run the simulation a few times, and confirm that your code is working. Using SortedAisle should result in relatively short average waits, but very long longest waits. People with lots of items will tend to get stuck at the end of the line while others continually cut in front of them.

Polymorphism

It is unfortunate that the current version of the simulation requires the code to be modified and recompiled when we want to change the aisle type used in the simulation. Modify the file MartDriver and MartSimulation classes to allow the user to select any of the three aisle types at run time. Execute the simulation several times to see the effect of changing aisle types.

Submit Customer.java, MartDriver.java, and SortedAisle.java to Gradescope .

6 - Inheritance Lab

Specialization in Java with Inheritance.

Inheritance in Bob’s Grocery Mart

Introduction

A previously introduced software solution, named for its first client “Bob’s Grocery Mart”, has been a big success. Cashiers are being scheduled more efficiently, and profits are up. However, Bob is concerned that some important factors are not captured by the current program. In particular, the simulation allows checkout lines to grow arbitrarily long. Beyond a certain length, real customers would choose to leave the store rather than waiting.

Your goal for this assignment is to modify the simulation so that customers will refuse to enter a checkout line if that line has reached some maximum capacity.

Instructions

  • Download the following files:
  • Take a few minutes to look over the existing classes to get a feel for how they work. Try executing MartDriver several times to see what the output looks like.
    • What is the average wait time with 12 cashiers?
    • What is the average wait time with 6 cashiers?
  • Create a new class that extends Aisle. As always, you should think carefully about what to name your class. One common convention in naming subclasses is to prefix the superclass name with an adjective the clarifies how the subclass specializes the superclass. For example, the Car class might have a subclass named ElectricCar. We recommended you call your class LimitedAisle.
    • Your new class must:
      1. Override the addCustomer method so that new customers are added only if the line is below some maximum capacity.
      2. Track the number of customers that refuse to wait because the line was too long.
  • Modify the simulation class so that it uses your new LimitedAisle subclass: everywhere “Aisle” appears in the existing class should be replaced with your “LimitedAisle”. You should modify the simulation constructor so that it accepts a “maximum length” parameter that describes maximum allowable length for a checkout line.
  • Modify the printResults method so that it reports the total number of customers that left the store because of excessive line lengths.
  • Test your new simulation using eight aisles, while keeping the other parameters at their default values. How many customers depart when maximum line length is 1? 5?, 20? (INCLUDE AN ANSWER TO THIS QUESTION IN A COMMENT AT THE BOTTOM OF YOUR NEW CLASS. )
  • Submit your completed LimitedAisle subclass and modified MartSimulation in Gradescope. It is your responsibility to make sure that the behavior is correct as the submission only checks if your code compiles. If you aren’t sure, check with your instructor or a TA.
  • If you have extra time:
    • Each time this simulation is executed, there is a different result. It might be valuable to know the average results across many different simulation runs. Add a new method to the MartSimulation class with the signature:
      public void runMany(int numRuns)
      
      This method should run the simulation the indicated number of times, and calculate averages for each of the quantities reported.

  • If you have even more time:

    It would be useful to be able to systematically adjust simulation parameters in small increments to see what effect this has on wait times etc. Add a loop to your main that systematically increases the maximum line length from 0 to 100. For each increment, run your simulation 100 times and report the average results.

7 - File I/O Lab

Work with file I/O in Java.

Introduction

The goal of this lab is to practice working with Java file I/O by adding load/save functionality to the Document class.

The code for this lab was originally designed as a command-line Java application so you may want to run it in the terminal. It is also fine to run it through the Eclipse console.

As a reminder, you can follow the following steps to compile and execute a Java program in a Linux/OSX terminal:

cd the_directory_where_your_code_is_stored
javac File1.java File2.java ...
java File1

This example assumes that File1.java contains the main method for the application.

Resources

Useful API documents:

Files

The following unfinished files are provided:

Instructions - Part 1

Download the files above and complete Document.java so that the unfinished methods conform to the Javadoc comments. Test your completed file by running the provided application program.

Instructions - Part 2

The current implementation of the Editor class does not include code for handling exceptions related to file I/O: If you attempt to open a non-existent file, or to write a file to a location where do not have permission, the application will crash.

Modify Editor.java by removing all throws declarations and adding try/catch blocks to saveFile and loadFile. If an exception occurs, these methods should print a helpful error message and then allow execution to proceed normally.

Instructions - Part 3 (If Time)

Most text editors allow you to save the current document without re-entering the file name. Modify the Editor class so that it provides this functionality. If the file is already associated with a file name (because of an earlier save or load) then the “s” command should now save the current version without prompting for a file name. You should also add a save-as command to allow specifying a file name even if one already exists. Use “w” to trigger save-as. Make sure to update the help message to conform to the new functionality.

Submitting

Submit your completed versions of Document.java and Editor.java to Gradescope . You have an unlimited number of submissions. If you have trouble with your submission, you may find it helpful to look at the JUnit submission tests:

8 - References

Work with references and arrays.

Complete the two Labs below:

  1. Lab: Experimenting with Reference Types
  2. Lab: Experimenting with Arrays and References

Then, answer the corresponding quiz in Canvas

The labs above are from Dr. David Bernstein. Thanks Dr. Bernstein!

9 - JUnit and EclEmma in Eclipse

Test your understanding of testing 😆. How to cover the implementation, considering the confidence afforded by coverage.
  1. complete the steps outlined on Dr. Bernstein’s Lab: Skills - JUnit and EclEmma in Eclipse

10 - Unit Testing Lab

What if I needed more forEquals methods than the Test class provides? Wanted a better summary of successes and failures? Wanted to measure how much of an implementation I’m testing?

Unit Testing and Code Coverage

Severe Weather Policy

The goal of this lab is to gain experience writing JUnit tests and using code coverage analysis.

Background

Suppose that JMU had the following severe weather cancellation policy: (here's the real one)

JMU (FAKE) SEVERE WEATHER POLICY

If any of the following conditions are met, campus will be closed:

  • More than 6.0 inches of rain are predicted within the next 24 hours.
  • Wind speeds greater than 70.0 mph are predicted within the next 24 hours.
  • It is predicted that there will be more than 4.0 inches of rain and wind speeds will be above 45.0 mph.

If none of the above conditions are met, the University may still issue a warning and encourage individuals to avoid non-essential outdoor activities. A warning will be issued if any of the following conditions are met:

  • Predicted wind speeds are above 45.0 mph.
  • Predicted precipitation is above 4.0 inches.

The following Java class has been developed as part of a JMU Decision Support system:

The weatherAdvice method provides an implementation of the cancellation policy above. Your job is to develop a set of JUnit tests to confirm that this method is implemented correctly. Your testing must also confirm that the correct exception is thrown when the method receives invalid input.

Part 1 - 100% Coverage

Creating a JUnit Test Class

Once you have set up an Eclipse project containing WeatherUtils.java, create a stub JUnit test class:

  1. Right click the WeatherUtils.java in the Package Explorer and select New -> JUnit Test Case. Make sure New JUnit Jupiter test is selected. Click the Next button, check the box for WeatherUtils, and click Finish (don’t worry if you see a warning against using the default package). This should prompt you to add Junit 5 to the build path and create a new file named WeatherUtilsTest.java.
  2. Write Javadoc comments so that Checkstyle is happy. For example:
    import static org.junit.jupiter.api.Assertions.*;
    import org.junit.jupiter.api.Test;
    
    /**
     * Tests the WeatherUtils class.
    *
    * @author
    * @version
    */
    public class WeatherUtilsTest {
    
        /**
         * Tests the weatherAdvice method.
         */
        @Test
        public void testWeatherAdvice() {
            fail("Not yet implemented");
        }
    
    }
    
  3. Replace the fail method call with an assertion, for example:
    assertEquals("CANCEL", WeatherUtils.weatherAdvice(70.1, 0.0));
    
  4. Run the JUnit test by clicking the green Run button on the toolbar. If you see a green bar on the left, your test passed; if you see a red bar, your test failed.
  5. You can now run coverage analysis against your program by clicking the button to the right of Run (this button should say Coverage in the tooltip when you hover your mouse cursor over it). This should color-code your Java files to indicate which lines are being exercised by your tests. You should also see a new tab labeled Coverage that will display coverage percentages for each file.
    • Note: Consider adjusting your theme away from Dark themes if the highlighting that indicates your test coverage makes the file nearly illegible (for some of the dark themes).
  6. You can select which coverage metric to display (Line Counters, Branch Counters, etc.) by clicking on the View Menu (3 vertical dots icon) in the far right of the Coverage window.

Writing Additional Tests

Complete WeatherUtilsTest.java by writing an appropriate set of test methods. You should be able to check your code coverage from within Eclipse. Keep working until your tests cover 100% of the method.

Once you are confident that your unit tests are sufficient, demonstrate them and your coverage to the instructor or TA. Your goal is to achieve 100% method, statement, and branch coverage.

Note: In order to cover the public class WeatherUtils line, you will need to construct a (useless) WeatherUtils object. The following example "covers" the default constructor. Notice that there is nothing to assert.

/**
 * Tests the constructor (for 100% coverage).
 */
@Test
public void testDefaultConstructor() {
    new WeatherUtils();
}

Testing for Exceptions

There are several ways to test for thrown exceptions in JUnit. For now, we propose you use the 1st method detailed in the JMU CS Wiki (pasted below for your convenience) , which involves your junit test catching the expected error, and using junit’s fail method after the line you expected to throw.

/**
 * Test that the constructor validates properly.
 * NOTE: the Atom class is just an example, the idea here is that the Atom
 * class's constructor should throw an IllegalArgumentException if the
 * atomic number or atomic weight are invalid (e.g. negative).
 */
@Test
public void constructor_IllegalArguments() {
    try {
        new Atom("O", -8, -16);

        // Shouldn’t get here
        fail("Constructor should have thrown an IllegalArgumentException");
    } catch (IllegalArgumentException iae) {
        // The exception was thrown as expected
    }   
}

Make sure you can answer the following questions:

  1. How do you write a test that confirms that the implementation throws an exception when specified?
  2. How do you write a test that confirms that the implementation does not throw an exception when specified not to?
  3. What does code coverage look like when exceptions are thrown? Is there any way to get 100% coverage for a test class that has exceptions?

Submission

Upload your completed WeatherUtilsTest.java file to Gradescope. To be graded, your code must (1) pass Checkstyle and (2) pass JUnit. If any of your tests fail, you will need to revise and resubmit.

Part 2 - Boundary Cases (Optional)

100% coverage doesn’t necessarily mean that your tests are good enough. High-quality tests should be able to uncover errors in the code that is being tested. The next step is to run your tests against an implementation that is known to contain errors. If your tests are effective, they should indicate that there is a problem with this code. For this part of the lab, you will run your tests against a pre-compiled .class file that we have intentionally coded to contain at least one error.

  1. Create a new Java Project.
  2. Copy your completed WeatherUtilsTest.java file into the new project, and make sure that JUnit is on the classpath (right-click the project, go down to Build Path, and click Add LibrariesJUnit…(ensure JUnit5 is selected)…Finish).
  3. Download the file WeatherUtils.class to anywhere but your Eclipse project folder
  4. Go to Project / Properties and click on Java Build Path.
  5. Click on Libraries -> Classpath -> Add External Class Folder. Navigate to the folder where you downloaded the WeatherUtils.class file.
  6. Press “Okay”. You will see a new section in the Package Explorer window called “Referenced Libraries” and you should see your new folder beneath it.
  7. Execute the tests to confirm that at least one test fails.

11 - Enum Lab

Imagine classes, but where the authors have predetermined all the instances that will ever exist.

Experimenting with Enumerated Types

For this lab you should:

  1. Ensure you know how to provide a command line argument for your program .
  2. complete the steps outlined on Dr. Bernstein’s Lab: Experimenting with Enumerated Types
  3. Submit your completed ShowAQI.java and AirQuality.java files to the assignment on Gradescope.

12 - Debugger Lab

Work with your IDE’s debugger to find and fix errors in your code.

Find the specification on Dr. Bernstein's website .

13 - Arrays Lab

Work with a random number generator to explore arrays, iteration, and decision making.

Background

Two 'D6's, six-sided dice

You will write today’s program from scratch. Create a new Java class named ArrayPlay with a main method. For each step below, you should add code to the program without replacing prior code. When you are finished, this program will provide you with a reference for working with arrays including initializing, printing, and comparing. This lab involves formatting Strings. If you haven’t completed the (Horstmann) Chapter 4 reading (especially 4.3.2), consider skimming it. You may also find the JDK documentation of the Formatter class (especially the Format String Syntax section) useful. Dr. Mayfield (et al.)’s ThinkJava2 available free online is also a handy supplemental resource (see e.g. its 3.5 Formatting Output , and consider learning this search engine operator since this version of the book doesn’t seem to provide a search mechanism).

Objectives

  1. Use an array to store a sequence of values.
  2. Display the contents of an array with a loop.
  3. Practice manipulating various types of arrays.
  4. Write methods using array parameters.

Key Terms

Array Initializer
list of values used to instantiate and initialize an array in one step (see more on Array Creation Expressions vs. Array Initializers, if you're curious actually those both go to higher dimensional arrays which is out of scope for this activity. Probably skimming ThinkJava2's Creating Arrays is a sufficient quick reference)
array.length
read-only attribute of an array that stores the number of elements
subscript (also "index")
integer value in brackets [ ] that specifies an element of an array
ArrayIndexOutOfBoundsException
error raised when trying to access a[i] where i < 0 or i >= a.length

Part 1: Sequentially accessing an array

Whenever you are asked to do something to your array and then print it, you should finish the update step first and then have a separate loop to do the printing.

  1. In the main method, create a single array of integers that is 6 elements long.
  2. Initialize each of the array elements to the value -1 using a loop of your choice.
  3. In another loop, print each element of the array with messages that look like:
    • array[0] = -1
      array[1] = -1
      ...
      
  4. Add code to change the value of each element of the array to its subscript. For example, array[3] should hold the value 3.
  5. Print the new contents of the array with the same message format as step 3. (You may copy and paste the code from step 3. Your program should now print both versions of the array.)
  6. add code to re-initialize your array contents to all zeros.
  7. Print the string Array Play (on its own line) to conclude Part 1.

Part 2: Randomly accessing an array

  1. Download Die.class for use in this Part and later. Assuming you created the Prerequisite File Hierarchy, you should then:
    1. Create a new directory (call it something about this activity, e.g. lab04) in the provided directory.
    2. move the Die.class file you downloaded into the newly directory.
    3. In Eclipse, right-click on the the current Java Project you’re using, and choose Properties... (last entry in the context menu).
    4. in the left pane, select Java Build Path.
    5. in the right pane, select the tab, labeled Libraries.
    6. click the Classpath item in the center pane.
    7. click the button no the far right, labeled Add External Class Folder....
    8. navigate to the provided directory and select the lab04 directory.
    9. Click Apply and Close.
  2. Create a new Die object.
  3. Create a loop that will iterate at least 100 times. In the loop body:
    1. Roll the die. (Don’t create a new object, just roll it again.)
    2. Based on the result of the roll, increment the corresponding cell of your array. The value of each array element should be the number of times that roll is made.
  4. After the loop finishes, print the results of the simulation. For example, if the array holds {20, 17, 19, 15, 12, 17} you would output (notice the empty line between each message):
    • 1 was rolled 20 times.
      
      2 was rolled 17 times.
      
      ...
      

Part 3: Working with multiple arrays

For this exercise, you will need two arrays of double values (I think I’ll name mine, minogue and oLeary).

  1. Use an array initializer { } to assign one of the arrays to 10 double values starting at 0.0 with each element 1.0 more than the previous (ending with the last element being set to 9.0).
  2. Instantiate the other array to store 10 elements, but do not initialize the contents yet.
  3. Print the contents of both arrays side by side on your screen, but first label this output by printing Before.
    • format the output as follows:
    • Before
      0 A1 = 0.0 A2 = 0.0
      1 A1 = 1.0 A2 = 0.0
      ...
      
  4. Copy the contents of the first array into the second, then print their contents again. Label this output After.
  5. Finally, change the element at index 0 of the first array to 99.0 and the element at index 5 of the second array to 99.0.
  6. Again, print the contents of the two arrays side by side. Label this output After Change.
  7. Check that the contents of the two arrays are indeed different. If not, make the appropriate corrections.

This is the expected output file for ArrayPlay: ArrayPlay.exp.

Part 4: Refactoring

In the lab so far, you were required to print all of the contents of an array several different times. Perhaps (as the instructions permitted) you did this by copying and pasting the same code several times. This is a bad practice. Instead, you should write a method that prints the contents of an array. This method should take the array as a parameter and print the contents of the array. You should then call this method from the appropriate places in your code.

+printArray(a: int[])

Write a (static and void) method named printArray that prints the contents of an array. The method should take the array as a parameter and print the contents of the array following the message format from Part 1. If the array is null, it should print the String null. If the array is empty, it should not print anything. You should then replace the code in your main method that prints the contents of the array with a call to this method.

+formMessage(a: int[], index: int, format: String): String

Write a static method named formMessage that defines 3 formal parameters:

  1. a is an array of integers.
  2. index is an integer that is the index of the array.
  3. format is a String that is a format string for the message. and from these parameters, returns a String that is the message for the provided array’s element at position index, with the given format. For example, if a holds {20, 17, 19, 15, 12, 17}, index is 3, and format is array[%d] = %d\n, the message would be: array[3] = 15\n. You should then replace the code in your printArray method that constructs the String to print with a call to this method. Note:
  4. you should not print anything in this method.
  5. if the provided array is null, you should return the String null.
  6. if the provided index is out of bounds, you should return the String index out of bounds.

+printArray(a: double[], b: double[])

Overload the printArray method to take two arrays of doubles as parameters. The method should print the contents of the two arrays side by side, with the first array’s elements on the left and the second array’s elements on the right. The method should print the contents of the arrays following the message format from Part 3. If either array is null, it should print the String null. If either array is empty, or if the arrays are not the same length as each other, it should not print anything. You should then replace the code in your main method that prints the contents of the arrays with a call to this method.

Submitting

Submit your final ArrayPlay.java file to Gradescope.

Acknowledgements 🙏

This lab is with thanks to at least Alvin Chao (, but likely also Nathan Sprague and David Bernstein ).

14 - Decisions

Classes in Java and their representation in UML.

Background

CodingBat is a free site of live problems to build skill in Java and/or Python. It was created by Nick Parlante, who is Computer Science lecturer at Stanford. The name “CodingBat” was based on the Greek word “bat” meaning “this domain was available” (or so they say).

Objectives

  • Practice writing small methods with conditionals and decisions.
  • Explore combined conditionals as substitutes for decision statements.
  • Observe the range of test cases needed to test decision statements.

Key Terms

unit test
A single example of running a small program unit, often a method.
expected value
The correct value a program should return for a unit test (aka test case).
actual value
The value a program actually returns for a unit test.
simplified code or boolean expression
A version of a piece of code that is less complicated or shorter than the original.

Part 0: Account Setup

  1. Go to codingbat.com and create an account (click the link on the upper right).
  2. Please use your JMU email when setting up your account.
  3. After logging in, click the “prefs” link (upper right) and “share to” your instructor’s email (duanzx@jmu.edu, stewarmc@jmu.edu) so you will get credit.
  4. Also make sure your name is entered as shown: Last, First

Part 1: Warm Up

As you begin to work CodingBat’s logic problems, you might find the CodingBat Boolean Logic page or their videos helpful:

  1. Java If Boolean Example Solution Code 1
  2. Java If Boolean Example Solution Code 2

Work through the following problems (all from Warmup-1 ). As you work through the problems notice that all of these have solutions available to you. Spend about 5 minutes trying each problem, before you look at the solution. When you are trying the problem and get the results, look at the test cases displayed by codingbat. Identify the expected and actual values. Notice that you may pass several tests, but not all of them. Unlike straight line code without decisions, conditionals and decision statements take a variety of test cases to make sure they work.

  1. sleepIn
  2. monkeyTrouble
  3. sumDouble
  4. diff21
  5. parrotTrouble
  6. makes10
  7. nearHundred
  8. posNeg

Part 2: String methods

Many of the problems on codingbat require you to use String methods that you may not yet have encountered. Check out especially:

  1. charAt
  2. equals
  3. length
  4. substring

Part 3: Warm-up with strings

Work through some of the Warmup-1 problems that require String methods:

  1. notString
  2. mixStart

Part 4: Problem Solving

  1. Solve the following problems (all from Logic-1 problems):
    1. squirrelPlay
    2. caughtSpeeding
    3. withoutDoubles
    4. shareDigit

  2. Solve the following problems ( from Logic-2 problems):
    1. roundSum
    2. blackjack

15 - Classes and UML Lab

Classes in Java and their representation in UML.

Introduction

The goal for this activity is to implement a Car class so that it conforms to the UML below:

classDiagram
class Car
  Car: -String make
  Car: -int year
  Car: -double speed
  Car: +Car(m String, y int)
  Car: +toString() String
  Car: +getMake() String
  Car: +getSpeed() double
  Car: +getYear() int
  Car: +accelerate() String
  Car: +brake() void

Part 1: Driver, Constructor and toString

  1. Create two Java class files: CarTester.java and Car.java. Only CarTester.java should include a main method.
  2. Add the three instance variables from the UML diagram to your Car class.
  3. Code the constructor for your Car class. This should initialize the make and year fields using the arguments to the constructor. The speed should be initialized to 0.
  4. Code the toString method. This method should take no parameters and should return a String that looks like this (except with the angle-bracketed parts replaced with this car's values):
    "A <year> <make> that is going <speed> mph"
    
  5. Test your partially completed Car class by adding code to the main in CarTester.java that creates and prints two car objects. The contents of main should look something like the following.
    Car car1;
    Car car2;
    
    car1 = new Car("Ford", 1997);
    car2 = new Car("Toyota", 2014);
    
    System.out.println(car1.toString());
    System.out.println(car2.toString());
    

Part 2: Remaining Methods

Complete each of the remaining methods of the Car class. Test each method by adding appropriate calls to main.

  • The three "getter" methods should each return the value of the appropriate instance variable.
  • The accelerate method should increase the current speed of the car by 5.0 mph. It should also return a String that describes the change to the speed, e.g. "15.0 + 5.0 = 20.0". It should NOT be possible to increase the speed beyond 150.0 mph. If a call to accelerate would push the speed beyond 150.0, the speed should be set to 150.0. (reaching this limit should be reflected in the returned String as well, i.e. "150.0 + 0.0 = 150.0")

    (How will you test that this is working correctly? How many times do you need to call accelerate before the upper speed limit is reached? Might a loop be helpful here?)

  • The brake method should decrease the current speed by 5.0 mph. It should not be possible for the speed to drop below 0 mph.

Submit Car.java only to Gradescope per your section's deadline. Gradescope will run Checkstyle tests on your submission.

Acknowledgements

Thank you to Dr. Sprague for this activity.

16 - Eclipse Lab

Verify your checkstyle and formatters are all setup correctly and that you know how to submit to Gradescope.

Introduction

In this lab, you will practice the process of creating a class in Eclipse and submitting it through Gradescope.

Before working on this lab, you should already have completed the steps in Installing Java and Eclipse .

Part 1 - Coding in Eclipse

  1. Create a new Eclipse project named PointLab:
    File -> New -> Java Project
    • Also uncheck the box that says “Create module-info.java file” or you will get an error saying “No source folder exists in the project”. (This error is harmless and can be ignored.) You should not have a module-info.java file in your project at any point this semester unless explicitly required by an assignment.
  1. Download the Point class that implements the specifications outlined in the UML and other notes below.
    1. right-click the link and choose Save Link As... and save the file in the newly created PointLab project, in its src folder.
classDiagram
class Point
Point : -double xPosition
Point : -double yPosition
Point : +Point(xPosition double, yPosition double)
Point : +getX() double
Point : +getY() double
Point : +setX(newX double) void
Point : +setY(newY double) void
Point : +equals(other Object) boolean
Point : +toString() String

Requirements

  1. The return value of the toString method should consist of an open-parenthesis followed by the x-coordinate, followed by a comma, then a space, then the y-coordinate followed by a close-parenthesis. For example: "(1.0, 2.0)".

  2. The equals method:

    • should return true if the other point has the same x and y coordinates.
    • Notice that the parameter type for the equals method is Object, not Point. This is the standard signature for an equals method: objects of different types should generally be considered not-equal, but it should still be possible to perform the comparison.
    • This means that equals method implementations are typically structured to use the instanceof operator as in the following example comparing instances of the (abridged) Person class below in which we imagine we consider a Person equal to another Person only when their names are the same (when in reality of course we all agree that all people are equal no matter their names 🟰):
      public class Person {
      
         private String name;
      
         // Other methods not shown...
      
         public boolean equals(Object other) {
      
            // Return false if other is not a Person.
            if (!(other instanceof Person)) {
                  return false;
            }
      
            // Cast other to Person so that we can access
            // members.
            Person otherPerson = (Person) other;
      
            // Now we can safely compare.
            return name.equals(otherPerson.name);
      
         }
      
      }
      
  3. Once you have completed a syntactically correct Point class, move on to the next step.

Part 2 - Checkstyle Eclipse Integration

  1. Recall that Checkstyle needs to be explicitly enabled for each new Eclipse project. Right click your PointLab project in the “Package Explorer” tab and then select Checkstyle -> Activate Checkstyle.
  2. Once you have completed the previous step, navigate to your file. Many lines of code in Point.java should now be marked with Checkstyle warnings. Each of these marked lines contains a violation of the style guidelines that would prevent you from successfully submitting a programming assignment. Clicking on the magnifying glasses in the left margin will show you a description of the problem. We’ll fix these problems in the next part of the lab.

Part 3 - Eclipse Auto-Formatting

Assuming that your auto-formatter is configured correctly, you should be able to re-format your Point.java file by selecting the entire file CTRL + A and then pressing CTRL + SHIFT + F. (usually on a mac the hotkeys are the same but you swap in command in place of CTRL)

  1. Once you have auto-formatted your code you must save it before Checkstyle will recheck it. Hopefully, many of the flagged formatting errors should now be gone. Most of the remaining issues probably relate to missing Javadocs.
  2. Add appropriate Javadoc comments to your Point class. Eclipse will automatically generate a Javadoc template for any method. You can either type /**+ENTER just above the method, or select the method and press SHIFT + ALT + J.
  3. Re-run Checkstyle, and address any remaining formatting issues.

Part 4 - Adding a .jar File

One standard mechanism for distributing Java code is through .jar files. A .jar file is a compressed archive that can hold any number of Java classes in either source or binary form (as .java files or as .class files). For some projects in this course you will be provided with .jar files containing support code.

  1. Create a new folder named ’lib’ in your Java project. Download the file PointCode.jar , and drag it into the newly-created folder.
  2. Right click PointCode.jar and select Build Path -> Add to Build Path.
  3. There should now be a “Referenced Libraries” entry in your project explorer. Expanding that entry should allow you to inspect the details of the PointCode.jar archive. All classes included in that archive are now available within your project. In this case there is only one class: PointDisplay.
    • Package Explorer showing referenced libraries
      • Package Explorer showing referenced libraries

Part 5 - Running

  1. Download the file PointDemo.java to your Desktop, then drag it into the default package section of your project.
  2. Look over the PointDemo class to get a feel for what it should do. Run the code to confirm that everything is working as expected.

Part 6 - JUnit

JUnit is a tool that makes it possible to automate the execution of Java test code. It is also the tool that is used by Gradescope to test your submissions. Don’t worry if you haven’t used JUnit before, we’ll spend more time on testing and JUnit later in the semester. For now, the goal is just to practice executing pre-written JUnit tests.

  1. Download the file PointTest.java and drag it into your PointLab project. These are exactly the tests that will be used by Gradescope when you submit Point.java at the conclusion of this activity.
  2. Initially, this file will not compile. If you open it up you will see that many of the lines of code are labeled as errors. The problem here is that JUnit isn’t part of the Java language. It is an external library that must be added to the Java Build path before it can be used. There are several different ways that this can be managed in Eclipse:
    • Option 1: You should see that the first underlined statement at the top of PointTest.java is this:
      import static org.junit.jupiter.api.Assertions.*;
      
    If you hover your mouse overorg.junit on this line, Eclipse will pop up a box with an error message (“the import org.junit cannot be resolved”) and the message “three quick fixes available:”. If you scroll to the bottom and select “Fix project setup” you should see a dialog offering to Add JUnit 5 library to build path. Click OK. Be careful! If it offers to add JUnit 4, cancel and try the next option instead.
    • Option 2: A simple trick that you can use to add JUnit to the build path is to ask Eclipse to auto-generate a JUnit test file. Just right-click on any file in your project and select New -> JUnit Test Case. Make sure the top radio button in the dialog is set to “New JUnit Jupiter test”. Keep the rest of the default options and click “Finish”. This should create a new test file (which you can delete) and add JUnit 5 to the build path.
  3. Once everything is compiling successfully, you can execute the tests by right-clicking PointTest.java and selecting Run As -> JUnit Test . Hopefully, all of the tests will pass. If not, fix the errors in Point.java before moving on to the next step.

Part 7 - Submitting Through Gradescope

  1. Submit Point.java through https://www.gradescope.com/ . You should have an email from your instructor that indicates you have been added to the course. If you have not used Gradescope before, you may need to create an account. If your code fails any of the submission tests, make any necessary modifications and resubmit until there are no failures.