2. String List v2026.sp

Notice

This document contains the description for the String List project assigned to the students in the Spring 2026 CSCI 1302 classes at the University of Georgia.

2.1. Project Deadlines

This String List project is broken up into three parts, and each part has its own deadline. The deadlines for each part are summarized in Table 2.1, and instructions are provided in the Project Checklist section later in this document.

Table 2.1 String List Deadlines

Part

Due Date

1

Friday, March 6th @ 11:55PM

2

Friday, March 20th @ 11:55PM

3

Wednesday, March 25th @ 11:55PM

To earn full points, you are required to submit all three parts. If you want extra credit, then complete and submit the first and / or second parts before their deadlines, as explained in the drop-down below.

Submission-Based (SB) Extra Credit

Students who perform their final submission for a Part 1 and / or Part 2 of the project via the specific submit1302 command mentioned for that part before its deadline stated in Table 2.1 will automatically receive +5 points of Submission-Based (SB) extra credit for that part. This assumes the submission also earns other credit since extra credit is extra and never intended to be the only credit earned.

If a student submits each part of the project correctly and on time, then the highest grade they can earn overall is 110 instead of 100.

Late Penalties

Late penalties do not start applying until after the final date/time listed in Table 2.1.

2.2. Project Preface

This second CSCI 1302 project for Spring 2026 is designed to help you apply and extend your prerequisite Java programming knowledge with new concepts from CSCI 1302 in a Unix development environment (i.e., Odin).

Motivation

This project will require you to apply some of the new concepts covered in CSCI 1302, including named packages, exception (creating and handling), and Java development in a Unix environment. It will also require you to utilize and apply object-oriented programming concepts like interfaces, inheritance, and polymorphism. If you have actively engaged with the CSCI 1302 course content offered so far this semester, then you should be able to comfortably, but not necessarily quickly, complete those aspects of the project by applying what you have practiced and learned from your content engagement.

Finally, this project may require you to do things that you have never been given explicit directions or instructions for — this is just a part of software development. In such cases, you may need need to do some research to help you plan your solution. That being said, we have carefully prepared this project description document so that it hopefully answers the majority of your questions. If not, then please do not hesitate to ask a question on the course Piazza or during office hours.

Academic Honesty

All students at the University of Georgia explicitly agree to abide by the UGA student honor code when they sign the application for their admission to the University. Additionally, all students enrolled in a CSCI 1302 course section in Spring 2026 are subject to the Academic Honesty policy included in the Spring 2026 CSCI 1302 course syllabus. Furthermore, anyone with access to this project description document is expected to respect the copyright and licensing terms provided or linked to at the bottom of this document and the starter code.

With academic honesty in mind, we ask all Spring 2026 CSCI 1302 students not to fork the project repository on GitHub. Doing so may make your copy of the project publicly visible, and that can violate several of the policies described earlier. Instead of forking the repository, please follow the instructions provided later in this document to acquire a copy of the project description and starter code.

Course-Specific Learning Outcomes

If you work on and complete this project, then you will gain exposure and practice with the following learning outcomes:

#

Exposure

Description

LO1.c

⭐⭐

Create and modify text files and source code using a powerful terminal-based text editor such as Emacs or Vi.

LO1.d

⭐⭐

Use shell commands to compile new and existing software solutions that are organized into multi-level packages and have external dependencies.

LO2.a

Identify redundancy in a set of classes and interfaces, then refactor using inheritance and polymorphism to emphasize code reuse.

LO2.b

⭐⭐

Define, throw, and propagate exceptions appropriately in a software solution.

LO3.a

⭐⭐

Create and update source code that adheres to established style guidelines.

LO3.b

Create class, interface, method, and inline documentation that satisfies a set of requirements.

LO4.c

Design, create and use inheritance relationships in a software solution.

LO7.c

Use common abstract data types and structures, including lists, queues, arrays, and stacks in solving typical problems.

Project Updates

If your instructor updates the project requirements or starter code before the project is due, then this section will be updated to include a summary of those updates and, if needed, instructions that describe how to update your working copy of the project with the latest versions of any changed files.

2.3. Project Description

In this project, you are tasked with writing and testing the code for two classes that each implement, in their own unique way, the Abstract Data Type (ADT) defined by the StringList interface.

Required Reading

Make sure that you have completed the readings listed below prior to starting this project:

You should also bookmark the following pages so that it is easier for you to refer to them while working on the project:

Introduction to String List Objects

Note: Packages included in cs1302-str-list.jar

Several of the UML diagrams in this project description include packages with a <<jar>> stereotype. For example, when a package includes the <<jar>> stereotype (like the one shown in Fig. 2.1), you should assume that package, including its classes and interfaces, are provided for you in the cs1302-str-list.jar file that is included in the project’s starter code.

You do not and must not recreate the classes and interfaces in these packages since they are already provided for you.

!includesub cs1302-str-list.puml!STYLE

package cs1302.adt <<jar>> {

}

Fig. 2.1 A UML diagram depicting a Java package that is included in the cs1302-str-list.jar file, as denoted by the inclusion of the <<jar>> stereotype displayed near the top of the package.

The cs1302.adt.StringList Interface

The StringList interface defines an ADT for managing a string list (i.e., a list of string references). You will NOT be writing the code for this interface yourself; instead, a compiled version of the StringList interface is provided for you in the cs1302-str-list.jar file (included in project’s the starter code), its full API documentation can be found here, and a short UML diagram depicting what it looks like is shown below in Fig. 2.2.

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST

Fig. 2.2 UML diagram for the StringList interface in the cs1302.adt package.

The Implementing Classes

In this project, you will implement the StringList interface two different ways. While both implementations will behave the same way from an outside perspective, each one will manage the storage data structure for its list items in a completely different way, as summarized in Table 2.2.

Table 2.2 Implementing classes and their storage data structures.

Implementing Class

Storage Data Structure

ArrayStringList

A simple, one-dimensional array object.

LinkedStringList

A linked list of Node objects.

Instead of writing every method two times (i.e., once for each class), you will create an abstract parent class named BaseStringList that will include some instance variables and methods that are common to both implementations.

A small UML diagram depicting how these classes are related is provided below in Fig. 2.3, and a more detailed UML diagram that includes the methods you are expected to include in each class is provided later in the project’s functional requirements section.

!includesub cs1302-str-list.puml!STYLE

package cs1302.adt <<jar>> {
  interface StringList <<interface>>
  class Node
}

package cs1302.p2 {
  abstract class BaseStringList <<abstract>>
  class ArrayStringList
  class LinkedStringList
}

BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends
LinkedStringList -up-|> BaseStringList : extends
LinkedStringList -up-> Node : dependsOn

Fig. 2.3 UML diagram depicting the relationships between the classes and interfaces in the cs1302.p2 and cs1302.adt packages. A more detailed version of this diagram that includes the instance variables and methods for each class and interface is provided in the project’s functional requirements section.

Tip

This project involves an interface, inheritance, and several classes, all of which can look daunting at first. Please take your time and read this entire project description before starting the project and be sure to follow the instructions for completing each part as they are described in the Project Checklist. You got this!

Using and Testing String List Objects

Tip

When you refer to the interface’s API documentation, you may be tempted to skip down the page to where the interface’s methods are documented since those are the methods that you will write for your implementing classes. Be sure to also read the interface-level documentation provided near the top of the page. It includes important definitions, examples, and even sample code that you are expected to understand before attempting to implement the interface’s individual methods.

Understanding ADT Expectations

Like most ADTs, we have expectations about how each method should behave when interacting with a string list object, even if we do not know or cannot see the internals of that object’s class. This is because the classes for such objects all implement the same ADT interface. These expectations are carefully documented in the interface’s API documentation.

For example, a new string list is expected to be size zero (i.e., its size() method is expected to return with 0), regardless of whether the calling object is an ArrayStringList, a LinkedStringList, or some other implementation of the StringList interface.

The examples in Listing 2.10 and Listing 2.11 illustrate this idea nicely. Even though each example involves a list object of a different type, they test for the same expected behavior in the exact same way by interacting with the object via the interface (via a StringList variable).

Listing 2.10 Sample test code that checks that the size() of a new ArrayStringList object is zero.
StringList list = new ArrayStringList();

int expectedSize = 0;
int actualSize = list.size();

if (list.size() != 0) {
    String message = String.format(
        "size(): expected %d, but %d",
        expectedSize,
        actualSize
    );
    throw new AssertionError(message);
} // if
Listing 2.11 Sample test code that checks that the size() of a new LinkedStringList object is zero.
StringList list = new LinkedStringList();

int expectedSize = 0;
int actualSize = list.size();

if (list.size() != 0) {
    String message = String.format(
        "size(): expected %d, but %d",
        expectedSize,
        actualSize
    );
    throw new AssertionError(message);
} // if
Testing that ADT Expectations are Met

In this project, you also need to write test code that work with objects any kind of StringList implementation, including the ArrayStringList and LinkedStringList classes that you are writing as well as the OracleStringList class that that is already provided for you in the project’s starter code.

The OracleStringList class fully and correctly implements the StringList interface; however, its Java source code is not made available to you. A compiled version of this class can be used by including the path to cs1302-str-list.jar on the class path when compiling and running code that uses it. You will use this class when developing the test code that you will write to make sure that your ArrayStringList and LinkedStringList classes behave correctly.

A simple UML diagram that depicts the relationship between the OracleStringList class and the classes that you will be writing is provided below in Fig. 2.4.

!includesub cs1302-str-list.puml!STYLE

package cs1302.adt <<jar>> {
  interface StringList <<interface>>
}

package cs1302.oracle <<jar>> {
  class OracleStringList
}

package cs1302.p2 {
  abstract class BaseStringList <<abstract>>
  class ArrayStringList
  class LinkedStringList
}

OracleStringList .up.|> StringList : implements
BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends
LinkedStringList -up-|> BaseStringList : extends

Fig. 2.4 UML diagram depicting the relationships between the OracleStringList class in cs1302.oracle, the StringList interface in cs1302.adt, and the classes that you will write in cs1302.p2.

Consider the code example in Listing 2.12, which is almost identical to the code provided earlier in Listing 2.10 and Listing 2.11. That is intentional.

All three examples test that the size() method for a new string list object behaves correctly; however, each example uses a different implementing class when constructing the object that size() is called on. Since they are all objects of classes that implement the same ADT interface, they are also all expected to exhibit the same observable behavior when interacting with them from the outside.

Listing 2.12 Sample test code that checks that the size() of a new OracleStringList object is zero.
StringList list = new OracleStringList();

int expectedSize = 0;
int actualSize = list.size();

if (list.size() != 0) {
    String message = String.format(
        "size(): expected %d, but %d",
        expectedSize,
        actualSize
    );
    throw new AssertionError(message);
} // if
ADT Expectations for Different Implementing Classes

Expectations regarding ADT behavior must hold true even if the implementing classes behave differently on the inside.

For example, the two different overrides that you will write for add(int, String) in ArrayStringList and LinkedStringList are going to look quite different from each other since each class uses a different storage data structure internally to manage its list items. Despite that, we have the same expectations about what we should observe from the outside when calling add(int, String) and other methods.

Remember, you have access to the OracleStringList class provided in the starter code. If you are ever unsure about how one of your overrides for an interface method is expected to behave under a certain scenario, then try that scenario using an OracleStringList object, observe what it does, then refer to the method’s API documentation to make sure you understand how that behavior is documented before attempting to make your version of the method behave the same way.

Project Testing Setup

Tip

The test code that you will write for this project is expected to properly test any valid implementation of the StringList interface. Since this interface defines an ADT we can write our tests based on the expectations and behavior described in its API documentation, just like in the examples illustrating how to test one expected behavior of the size() method in Listing 2.10, Listing 2.11, and Listing 2.12.

One Set of Test Methods

Instead of writing the same test code multiple times, once for each implementation, simply write it once using the interface type and swap out the specific implementation that you want to test. To help you get started, the starter code for StringListTester.java is setup to let you do just that.

A simple UML diagram is provided below in Fig. 2.5 that illustrates some of the key pieces that enable this reusable testing setup to work. In particular, pay close attention to the newStringList() method and how that method is used in the example code provided for testScenario1().

!includesub cs1302-str-list.puml!STYLE

package cs1302.adt <<jar>> {
  interface StringList <<interface>>
}

package cs1302.oracle <<jar>> {
  class OracleStringList
}

package cs1302.p2 {
  abstract class BaseStringList <<abstract>>
  class ArrayStringList
  class LinkedStringList
}

package cs1302.test {
  class StringListTester {
    + newStringList(): StringList
    + testScenario1(): void
    + testScenario2(): void
    {method} ⋮
    + testAll(): void
    + {static} main(args: String[]): void
  }
}

OracleStringList .up.|> StringList : implements
BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends
LinkedStringList -up-|> BaseStringList : extends
StringListTester -left-> StringList : dependsOn

note right of StringListTester::newStringList
  public StringList newStringList() {
      // UNCOMMENT A LINE BELOW TO TEST THAT CLASS
      // return new OracleStringList();
      // return new ArrayStringList();
      // return new LinkedStringList();
  } // newStringList
end note

note right of StringListTester::testScenario1
  public void testScenario1() {
      StringList list = this.newStringList();
      int expected = 0;
      int actual = list.size();
      if (actual != expected) {
          throw new AssertionError("...");
      } // if
  } // testScenario1
end note

note right of StringListTester::testAll
  public void testAll() {
      this.testScenario1();
      this.testScenario2();
      ⋮
  } // testAll
end note

note right of StringListTester::main
  public static void main(String[] args) {
      StringListTester tester = new StringListTester();
      System.out.printf(
          "%sTester\n",
          tester.newStringList().getClass().getName()
      );
      tester.testAll();
  } // main
end note

Fig. 2.5 UML diagram illustrating some of the key pieces that enable the reusable testing setup in the StringListTester class to work.

A few test scenarios are provided for you in the starter code; however, they are not to be considered complete or exhaustive. They are mostly provided to help you get started writing your own test code more quickly.

Additional Details

One goal for this project is to end up with completed versions of the ArrayStringList and LinkedStringList classes that both extend the BaseStringList class and provide a different, concrete implementations of StringList interface that meets the project’s functional and non-functional requirements.

Implementers are always free to implement additional methods in addition to the ones defined by the interface. However, they should not assume that users (e.g., graders) will use these additional methods, even if declared with public visibility, since those methods cannot be called when using a StringList variable. Such methods can still be extremely useful in helping you avoid redundancy across methods within an implementation.

Getting Started

You will not be starting from scratch. Instead, starter code is provided that you will need to download to get started, then modify and test to meet the project’s requirements. To download the starter code, follow these instructions:

  1. Login to Odin.

  2. If you have not done so, we recommend creating a separate directory inside of your home directory to store all of your CSCI 1302 projects instead of having them all directly inside your home directory.

  3. Change to your CSCI 1302 projects directory.

  4. Execute the following command to download the starter code into a sub-directory called cs1302-str-list:

    Listing 2.13 The git command to download a clone of the project’s starter code.
    git clone --depth 1 https://github.com/cs1302uga/cs1302-str-list.git
    
  5. Change to the cs1302-str-list directory that was just created, then use the tree command to verify that you now have a copy of the starter code:

    Listing 2.14 Output of running the tree command directly inside the cs1302-str-list directory.
    tree --filesfirst
    
    .
    ├── compile.sh
    ├── jdeps.sh
    ├── LICENSE.rst
    ├── README.rst
    ├── SUBMISSION.md
    ├── test.sh
    ├── lib
    │   └── cs1302-str-list.jar
    └── src
        └── cs1302
            ├── p2
            │   ├── ArrayStringList.java
            │   ├── BaseStringList.java
            │   └── LinkedStringList.java
            └── test
                └── StringListTester.java
    
    Descriptions of the files included in the starter code

    A short description for each file contained in the starter code can be found below in Table 2.3.

    Table 2.3 Descriptions of files included in the starter code for cs1302-str-list.

    File

    Description

    compile.sh

    A script that compiles the starter code.

    jdeps.sh

    A script that shows the dependencies between types in your compiled code.

    LICENSE.rst

    A copy of the license for starter code.

    README.rst

    A small README file that points students to the project description.

    SUBMISSION.md

    A file that you will update to include your name API documentation link.

    test.sh

    A script that runs the tester included in the starter code.

    cs1302-str-list.jar

    A JAR file containing some already-compiled files included in the starter code.

    BaseStringList.java

    The starter code for an abstract parent class for StringList implementations.

    ArrayStringList.java

    The starter code for an array-based StringList implementation.

    LinkedStringList.java

    The starter code for a linked-list-based StringList implementations.

    StringListTester.java

    The starter code for a reusable tester class for StringList implementations.

  6. Modify the SUBMISSION.md file to meet the project requirement related to that file (stated here).

    Listing 2.15 The emacs command to open SUBMISSION.md.
    emacs SUBMISSION.md
    

    Make sure that you save the file before continuing to the next step.

  7. Your cs1302-str-list directory is managed by a local Git repository (hidden under a .git directory), which means you should be able to stage the change that you just made to SUBMISSION.md, then commit that change to add it to the repository’s history.

    Instructions: Stage and commit your SUBMISSION.md changes
    1. Check the current status of the local Git repository (refer to Listing 2.16 to see the exact command to use):

      Listing 2.16 The git command to see the current status of the local Git repository. You should see output similar to what is shown below if you the only thing you have done so far is clone the starter the code and modified your SUBMISSION.md file.
      git status
      
      On branch main
      Your branch is up to date with 'origin/main'.
      
      Changes not staged for commit:
        (use "git add <file>..." to update what will be committed)
        (use "git restore <file>..." to discard changes in working directory)
       modified:   SUBMISSION.md
      
      no changes added to commit (use "git add" and/or "git commit -a")
      
    2. Add SUBMISSION.md to the list of files that are “staged” for the next commit (refer to Listing 2.17 to see the exact command to use):

      Listing 2.17 The git command to add SUBMISSION.md to the list of files that are “staged” for the next commit. This “add” command will not produce any output unless Git encounters an error while performing it.
      git add SUBMISSION.md
      
    3. Check the current status of the local Git repository again to confirm that SUBMISSION.md is now included in the list of files that are “staged” for the next commit (refer to Listing 2.18 to see the exact command to use):

      Listing 2.18 The git command to see the current status of the local Git repository. You should see output similar to what is shown below if you are following along and the last thing you did was “add” your modified your SUBMISSION.md to the list of files that are “staged” for the next commit.
      git status
      
      On branch main
      Your branch is up to date with 'origin/main'.
      
      Changes to be committed:
        (use "git restore --staged <file>..." to unstage)
            modified:   SUBMISSION.md
      
    4. Commit the staged changes to repository’s history (refer to Listing 2.19 to see the exact command to use):

      Listing 2.19 The git command to commit the list of staged files to repository’s history with the log message specified using the -m option. When you run this command, the output will show a different value for the commit hash (i.e., not ???????).
      git commit -m "added my info to SUBMISSION.md"
      
      [main ???????] added my info to SUBMISSION.md
       1 file changed, 1 insertion(+), 1 deletion(-)
      
    5. Confirm that the “commit” is now included in the repository’s history with the message that was specified when it was committed (refer to Listing 2.20 to see the exact command to use):

      Listing 2.20 The git command to view the log for the local Git repository (i.e., its history of commits). When you run this command, the output will show a different value for the top-most commit hash (i.e., not ???????).
      git log --decorate --oneline --graph
      
      * ??????? (HEAD -> main) added my info to SUBMISSION.md
      * 141e8b4 (origin/main) starter code commit
      
  8. Proceed to the Project Checklist to see the instructions for each part of the project.

2.4. Project Checklist

The steps in the following checklist assume you have already read the other parts of the project description. The first time that you read this section, simply take notes, then reread it again later to begin working on the project.

Part 1. Prepare and Plan (due Friday, March 6th @ 11:55PM)

Preparing for Part 1

Follow the steps provided below to prepare the BaseStringList, ArrayStringList, and LinkedStringList classes so that everything compiles and so that you can test ArrayStringList and LinkedStringList with the same test code provided in cs1302.test.StringListTester.

Due Before:

Friday, March 6th @ 11:55PM.

  1. If you have not yet done so, download the starter code on Odin by following the instructions in the Getting Started dropdown provided earlier in this document.

  2. Based on the API documentation for StringList and the UML diagrams provided in the Overview: UML Diagrams dropdown and elsewhere under the project’s Functional Requirements, add “stub” methods (or placeholders that let us compile the code without fully implementing a method) for the specific method overrides that expected to be declared in BaseStringList, ArrayStringList, and LinkedStringList, in that order.

    How to identify the methods to declare

    Refer to the UML diagrams shown in the Overview: UML Diagrams dropdown under the project’s Functional Requirements. The “Default UML” diagram in the first tab shows exact overrides that must be declared inside BaseStringList.java, ArrayStringList.java, LinkedStringList.java.

    You should notice that BaseStringList does NOT declare an override for every abstract method listed in the StringList interface. That is okay since BaseStringList is abstract. Any method overrides that are missing can still be called, assuming they are eventually “filled in” by an override declared in a concrete child class.

    How to write a “stub” method for an override

    Refer to Listing 2.21 below for an example of what a “stub” for the size() method override that is expected to be declared in BaseStringList.java. Not only are you permitted to copy this example directly into your BaseStringList class, you can base your other “stub” methods on it as well.

    Listing 2.21 Example “stub” method for the size() method.
    /**
     * Returns the number of items in this string list.
     * {@inheritDoc}.
     */
    @Override
    public int size() {
        // TODO: describe the plan for this method
        throw new UnsupportedOperationException("not yet implemented");
    } // size
    
  3. As soon as you have valid “stub” methods added for the appropriate overrides in BaseStringList, ArrayStringList, and LinkedStringList, you should be able to compile your project code using the compile.sh interpreter script that is included in the project’s starter code (see Listing 2.22).

    Listing 2.22 The command to execute the compile.sh interpreter script.
    ./compile.sh
    
    The actions performed by compile.sh

    You are encouraged to inspect the compile.sh script to see what commands it executes. At a high-level, it attempts to execute commands for the actions listed below in Table 2.4 until an action fails or or all the actions complete successfully:

    Table 2.4 A list of the high-level actions performed by compile.sh.

    #

    Action

    Description

    1

    clean

    Delete all files under bin and doc so that you do not risk accidentally using an old version of a compiled class or interface.

    2

    compile

    Compile the BaseStringList, ArrayStringList, LinkedStringList, and cs1302.test.StringListTester classes to the bin directory using the javac command

    3

    document

    Generate the files for API documentation website and place them in the doc directory using the javadoc command.

    4

    lint

    Check all the .java files under src for code style violations using the check1302 command.

    Important

    If you encounter any errors or warnings when running the compile.sh script, then you should always fix them before proceeding. This includes any errors or warning emitted by the javadoc and check1302 commands in addition to those emitted by the javac command.

  4. Now that you have everything setup so that it compiles without any errors or warnings, you should stage and commit the changes that you have made to BaseStringList.java, ArrayStringList.java, and LinkedStringList.java using Git.

    Hint

    You can follow the same process described earlier in Getting Started to accomplish this, but take care to specify a different commit message that more accurately describes the work that has been done since your last commit.

  5. Now it is time to come up with a plan for each method override. Assuming each of your “stub” methods looks like the example shown in Listing 2.21, simply replace the “// TODO” comment with one or more comments that list out the high-level steps that you think need the method needs to perform.

    Tips for planning

    Tip

    The BaseStringList does not set anything up to store list items; however, the method overrides declared in this class can call any of the methods available from the interface, even those that are not overridden in BaseStringList itself under the assumption that such a call will get “filled in” with by an override in a child class.

    Tip

    Be sure to read everything up to the “Method Details” section. That section is important but will make more sense later – you will want to reference it when you are ready to start writing code. Also be sure to carefully trace through any code examples that are given. These will help you understand how your class(es) will be used.

    Tip

    You need to make sure that you understand what a potential call to each method might look like and what a user would expect to happen when making that call on an object of an implementing class. Use the method documentation and code examples in the interface’s API documentation to get started.

    Tip

    For each method in the interface, try to write down what you think the basic steps need to be in order to produce the desired outcome.

    • Try to keep it high level. If the steps that you write down sound like they can be accomplished with another method, then replace those steps with a note to refer to that method. If that other method does not yet exist, then you might introduce that as a private or protected helper method. Using existing methods can greatly cut down the amount of code you need to write and will minimize the number of bugs in your code.

    • Here is an example: If there are multiple methods that have a step that gets an element from a specific index in the list, then you might have that method call the get(int) method instead of directly accessing the underlying data structure (array or linked list) which might require writing the same loop multiple times.

    • Consider drawing out memory map diagrams similar to the ones shown in the List ADT - Examples with Both Implementations section of the textbook.

    Based on the previous suggestion, draw out what the method dependencies are for each method (i.e., what method depends on what). If you notice any circular dependencies, then those should be eliminated.

    • The methods that do not depend on other methods are good candidates to start with when you begin the next phase of your development. We will call these the independent methods.

    Specific planning steps for each file

    Here are the specific steps that you should follow to add your planning comments to each file:

    1. Add your planning comments to the stub methods in BaseStringList.java, save it, and make sure it still compiles without any errors or warnings using the compile.sh script. After that, stage and commit your changes to that file using Git.

    2. Add your planning comments to the stub methods in ArrayStringList.java, save it, and make sure it still compiles without any errors or warnings using the compile.sh script. After that, stage and commit your changes to that file using Git.

    3. Add your planning comments to the stub methods in LinkedStringList.java, save it, and make sure it still compiles without any errors or warnings using the compile.sh script. After that, stage and commit your changes to that file using Git.

  6. Modify the newStringList() method in cs1302.test.StringListTester to return a reference to a new OracleStringList object, then run the test.sh interpreter script that is included in the project’s starter code (see Listing 2.23).

    Listing 2.23 The command to execute the test.sh interpreter script.
    ./test.sh
    
    The actions performed by test.sh

    You are encouraged to inspect the test.sh script to see what commands it executes. At a high-level, it attempts to execute commands for the actions listed below in Table 2.5 until an action fails or or all the actions complete successfully:

    Table 2.5 A list of the high-level actions performed by test.sh.

    #

    Action

    Description

    1

    compile

    Run the compile.sh script.

    2

    test

    Run the cs1302.test.StringListTester class using the java command.

    Important

    If you encounter any errors when cs1302.test.StringListTester tests a specific scenario, then that is great! If you encounter an AssertionError, then that means the implementation you are testing does not meet some behavior expectation.

    Use the output provided in the stack trace to determine which test scenario failed and what expectation was not met so that you more quickly locate where to start addressing the issue in your code.

  7. At this point, you should have a complete project environment set up with “stub” methods, planning comments, and one or more tester programs that you can adjust and run to check the functional correctness of your code as you begin to implement it during the next part of the project.

  8. Before Friday, March 6th @ 11:55PM, follow the submission instructions to prepare Part 1 of your project for submission and actually submit it.

Part 2. Implement ArrayStringList (due Friday, March 20th @ 11:55PM)

Preparing for Part 2

To prepare for this part of the project, you must first complete and submit Part 1. Also, even though you are not finalizing the code for the overall project during this part, your submission for this part is still expected to meet all the non-functional requirements stated later in the project description.

Due After:

Submitting Part 1.

Due Before:

Friday, March 20th @ 11:55PM.

  1. Modify the newStringList() method in cs1302.test.StringListTester to return a reference to a new ArrayStringList object, then run the test.sh script (see Listing 2.24).

    Listing 2.24 The command to execute the test.sh interpreter script.
    ./test.sh
    

    StringListTester is Expected to Fail!

    Since you have not fully implemented any of the methods that you added as “stub” methods yet, you should see the tester program crash when test.sh runs cs1302.test.StringListTester using the java command.

    Once you confirm that your tester is testing the ArrayStringList class but failing (as expected), stage and commit your changes using the appropriate Git commands.

  2. Implement and test the methods below in the order presented by following the specific steps stated in the next dropdown for each method:

    Table 2.6 The methods to implement and test for Part 2.

    #

    Class

    Method

    1

    BaseStringList

    int size()

    2

    BaseStringList

    boolean isEmpty()

    3

    ArrayStringList

    boolean add(int, String)

    4

    ArrayStringList

    String get(int)

    5

    BaseStringList

    String makeString(String, String, String)

    6

    BaseStringList

    String toString()

    7

    BaseStringList

    boolean contains(int, String)

    8

    ArrayStringList

    void clear()

    9

    ArrayStringList

    String remove(int)

    10

    ArrayStringList

    StringList reverse()

    11

    ArrayStringList

    StringList slice(int, int)

    12

    BaseStringList

    boolean add(int, StringList)

    Specific steps for each method

    Here are the specific steps that you should follow to implement and test each method listed earlier in Table 2.6:

    1. Read the planning comments that you included in the method “stub” that created for the current method.

    2. Add test methods for one or more test scenarios that involve the current method to your cs1302.test.StringListTester class, then make sure that those test methods work with OracleStringList by temporarily adjusting the newStringList() method to return a new OracleStringList object and running the test.sh script. Once your test methods compile and pass correctly for OracleStringList using test.sh, adjust the newStringList() method to return a new ArrayStringList object, then stage and commit your changes using the appropriate Git commands.

    3. Adjust the code for the current method by removing the throw-statement for the UnsupportedOperationException and writing some code to instruct the computer to follow your plan. Use the test.sh test to compile and test your code. If you encounter an issue, use the information that you see narrow down what and where the issue is, then attempt to modify the code to resolve that issue. Repeat, as needed, until the current method passes its tests. After that, stage and commit your changes using the appropriate Git commands.

  3. Before Friday, March 20th @ 11:55PM, follow the submission instructions to prepare Part 2 of your project for submission and actually submit it.

Part 3. Implement LinkedStringList (due Wednesday, March 25th @ 11:55PM)

Preparing for Part 3

To prepare for this part of the project, you must first complete and submit Part 2. Also, please remember that your submission for this part is expected to meet all the functional requirements and non-functional requirements stated in the project description.

Due After:

Submitting Part 2.

Due Before:

Wednesday, March 25th @ 11:55PM.

  1. Modify the newStringList() method in cs1302.test.StringListTester to return a reference to a new LinkedStringList object, then run the test.sh script (see Listing 2.25).

    Listing 2.25 The command to execute the test.sh interpreter script.
    ./test.sh
    

    StringListTester is Expected to Fail!

    Since you have not fully implemented any of the methods that you added as “stub” methods to LinkedStringList, you should see the tester program crash when test.sh runs cs1302.test.StringListTester using the java command.

    Once you confirm that your tester is testing the LinkedStringList class but failing (as expected), stage and commit your changes using the appropriate Git commands.

  2. Implement and test the methods below in the order presented by following the specific steps stated in the next dropdown for each method:

    Table 2.7 The methods to implement and test for Part 3.

    #

    Class

    Method

    1

    LinkedStringList

    boolean add(int, String)

    2

    LinkedStringList

    String get(int)

    3

    LinkedStringList

    void clear()

    4

    LinkedStringList

    String remove(int)

    5

    LinkedStringList

    StringList reverse()

    6

    LinkedStringList

    StringList slice(int, int)

    Specific steps for each method

    Here are the specific steps that you should follow to implement and test each method listed earlier in Table 2.7:

    1. Read the planning comments that you included in the method “stub” that created for the current method.

    2. You should already have one or more test methods for the current method (from completing Part 2), but add more test methods, as needed to check any scenarios that you did not consider previously. If you add any new test methods to your cs1302.test.StringListTester class, then make sure that those test methods work with OracleStringList by temporarily adjusting the newStringList() method to return a new OracleStringList object and running the test.sh script. Once your test methods compile and pass correctly for OracleStringList using test.sh, adjust the newStringList() method to return a new ArrayStringList object, then stage and commit your changes using the appropriate Git commands.

    3. Adjust the code for the current method by removing the throw-statement for the UnsupportedOperationException and writing some code to instruct the computer to follow your plan. Use the test.sh test to compile and test your code. If you encounter an issue, use the information that you see narrow down what and where the issue is, then attempt to modify the code to resolve that issue. Repeat, as needed, until the current method passes its tests. After that, stage and commit your changes using the appropriate Git commands.

  3. Final Run-through.

    • Thoroughly test all of your methods on objects of both ArrayStringList and LinkedStringList using one or more tester programs.

    • Remember to fix errors and warning as you go, including code style violations, and to fully stage and commit your changes every time you confirm that something works.

  4. Before Wednesday, March 25th @ 11:55PM, follow the submission instructions to prepare Part 3 of your project for submission and actually submit it.

2.5. Functional Requirements

A functional requirement defines a specific behavior between program inputs and outputs, and a collection of functional requirements describes how a program should function. If your submission satisfies a functional requirement listed in this section, then the requirement’s point total is added to your submission grade.

Overview

For this project, you are required to create two different classes that implement the same interface via a common abstract parent. While the specific details are listed later in this document, the following diagram illustrates the general relationship between your classes and the interface. The package cs1302.adt is provided for you in the cs1302-str-list.jar file that is included in the starter code.

UML Diagrams

The UML diagram below in Fig. 2.6 shows the packages, classes, and interfaces involved in this project.

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!NODE
!includesub cs1302-str-list.puml!BASESTRINGLIST
!includesub cs1302-str-list.puml!ARRAYSTRINGLIST
!includesub cs1302-str-list.puml!LINKEDSTRINGLIST
!includesub cs1302-str-list.puml!ORACLE_STRINGLIST
!includesub cs1302-str-list.puml!LIST_TESTER

OracleStringList .right.|> StringList : implements
BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends
LinkedStringList -up-|> BaseStringList : extends
LinkedStringList -up-> Node : dependsOn
StringListTester --> StringList : dependsOn

Fig. 2.6 UML diagram depicting the packages, classes, and interfaces involved in this project.

The UML diagram below in Fig. 2.7 shows the packages, classes, and interfaces involved in this project. The level of detail it provides for the classes in the cs1302.p2 package is expanded to show all the methods that are available in each class and not just the methods that are declared there.

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!NODE
!includesub cs1302-str-list.puml!BASESTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!ARRAYSTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!LINKEDSTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!ORACLE_STRINGLIST
!includesub cs1302-str-list.puml!LIST_TESTER

OracleStringList .right.|> StringList : implements
BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends
LinkedStringList -up-|> BaseStringList : extends
LinkedStringList -up-> Node : dependsOn
StringListTester --> StringList : dependsOn

Fig. 2.7 UML diagram depicting the packages, classes, and interfaces involved in this project with more details depicting what methods are available in each class in cs1302.p2.

The UML diagram below in Fig. 2.7 shows the packages, classes, and interfaces involved in this project. The level of detail it provides for the classes in the cs1302.p2 package is expanded to show all the methods that are available in each class and not just the methods that are declared there. This version also includes notes that show what the constructors for those classes look like.

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!NODE
!includesub cs1302-str-list.puml!BASESTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!ARRAYSTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!LINKEDSTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!ORACLE_STRINGLIST
!includesub cs1302-str-list.puml!LIST_TESTER

OracleStringList .right.|> StringList : implements
BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends
LinkedStringList -up-|> BaseStringList : extends
LinkedStringList -up-> Node : dependsOn
StringListTester --> StringList : dependsOn

package cs1302.p2 {

  note left of BaseStringList::BaseStringList
    public BaseStringList() {
        super();
        this.size = 0;
    } // BaseStringList
  end note

  note left of ArrayStringList::ArrayStringList
    public ArrayStringList() {
        super();
        this.items = new String[3];
    } // ArrayStringList
  end note

  note left of LinkedStringList::LinkedStringList
    public LinkedStringList() {
        super();
        this.head = null;
    } // LinkedStringList
  end note

}

Fig. 2.8 UML diagram depicting the packages, classes, and interfaces involved in this project with more details depicting what methods are available in each class in cs1302.p2 as well as notes that show what the constructors for those classes look like.

If you setup your constructors as depicted above in Fig. 2.8, then any new ArrayStringList and LinkedStringList objects that are created at runtime should look like the ones depicted in the memory map shown below for Listing 2.26.

Listing 2.26 Memory map visualizing a program’s memory after constructing two different kinds of string list objects, assuming the constructors are structured as depicted in Fig. 2.8.
StringList list1 = new ArrayStringList();
StringList list2 = new LinkedStringList();
code visualization

Fig. 2.9 Memory map visualizing a program’s memory after constructing two different kinds of string list objects, assuming the constructors are structured as depicted in Fig. 2.8. Note: The debugger breakpoint is on line 5. [code listing]

code visualization

Fig. 2.10 Memory map visualizing a program’s memory after constructing two different kinds of string list objects, assuming the constructors are structured as depicted in Fig. 2.8. Note: The debugger breakpoint is on line 6. [code listing]

Using what is in the JAR file

You do not have access to the source code for classes in cs1302.adt. However, you do have access to the byte code and the API documentation website. You will need to use both StringList and Node in your code because BaseStringList directly implements StringList and LinkedStringList depends on Node.

cs1302.p2.BaseStringList
Starter Code

The cs1302.p2.BaseStringList class is one of the classes that you are responsible for implementing and testing. A partially implemented version of this file is included in the starter code. It is your responsibility to ensure that it is placed under src and named correctly based on the information provided below.

Table 2.8 Starter Code for cs1302.p2.BaseStringList

Item

Description

Source

src/cs1302/p2/BaseStringList.java

FQN

cs1302.p2.BaseStringList

Package Name

cs1302.p2

Simple Name

BaseStringList

UML Diagrams

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!BASESTRINGLIST

BaseStringList .up.|> StringList : implements

Fig. 2.11 UML Diagram …

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!BASESTRINGLIST_DETAILS

BaseStringList .up.|> StringList : implements

Fig. 2.12 UML Diagram …

Class Design

Create the abstract BaseStringList class such that it properly implements a subset of the abstract methods of StringList. Since BaseStringList is abstract, it is not mandatory to implement all methods of StringList within this class. The exact methods this class must implement are listed in the method section for BaseStringList in the UML diagram.

Remember, since BaseStringList is an abstract parent to both ArrayStringList and LinkedStringList, its methods must be implemented without reference to the underlying data structure. In other words, within BaseStringList, you cannot use arrays or nodes. The code contained in this class must be general enough to work with both.

Note

The size instance variable in BaseStringList is shown as #size in the UML diagram to designate that it has _protected_ visibility and, therefore, must be declared in your Java code using the protected visibility modifier. The child classes of BaseStringList inherit their own copies of this protected size instance variable and have direct access to them. This variable should be initialized in the BaseStringList constructor. You must NOT re-declare the size variable in either of the child classes. For more information about _protected_ visibility, refer to the Protected Visibility reading.

Note

The methods that are listed in the UML diagram in BaseStringList must be implemented in that class. You are not allowed to move any of them into ArrayStringList or LinkedStringList. You may, however, find that you can move one or more methods from ArrayStringList and LinkedStringList up into BaseStringList. Moving methods up is allowed. In fact, it is encouraged. Any method that you can move up only has to be written once! However, accomplishing this will require some thought. We hope that all of you spend some time trying to ensure that ArrayStringList and LinkedStringList only contain the methods that absolutely need to be implemented in the child classes!

Dependencies

It should also be noted that the BaseStringList class depends on some classes that we have included in cs1302-str-list.jar.

Class / Interface

Description

StringList

An ADT / interface for a sequence of references to non-empty String objects.

You do not have access to the source code for the classes and interfaces in that Java ARchive (JAR) file; however, API documentation for those classes is provided api|_.

The compilation instructions that we provide below will ensure that these dependencies are available on the classpath so that the compiler can find them.

How to Compile

To compile BaseStringList.java, execute the following command while directly inside the cs1302-str-list directory:

javac -Werror -g \
    -cp lib/cs1302-str-list.jar -d bin \
    src/cs1302/p2/BaseStringList.java
cs1302.p2.ArrayStringList
Starter Code

The cs1302.p2.ArrayStringList class is one of the classes that you are responsible for implementing and testing. A partially implemented version of this file is included in the starter code. It is your responsibility to ensure that it is placed under src and named correctly based on the information provided below.

Table 2.9 Starter Code for cs1302.p2.ArrayStringList

Item

Description

Source

src/cs1302/p2/ArrayStringList.java

FQN

cs1302.p2.ArrayStringList

Package Name

cs1302.p2

Simple Name

ArrayStringList

UML Diagrams

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!BASESTRINGLIST
!includesub cs1302-str-list.puml!ARRAYSTRINGLIST

BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends

Fig. 2.13 UML Diagram …

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!BASESTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!ARRAYSTRINGLIST_DETAILS

BaseStringList .up.|> StringList : implements
ArrayStringList -up-|> BaseStringList : extends

Fig. 2.14 UML Diagram …

Class Design

Create the ArrayStringList class such that it properly extends BaseStringList and fully implements the StringList interface with additional requirements listed below.

  • You must explicitly define and document a default constructor for this class. The initial size of an ArrayStringList is 0 regardless of the list’s underlying storage — remember, the list’s internal storage and the list itself are two different things. Here is the signature:

    public ArrayStringList() {
    
  • Over the lifetime of an ArrayStringList object, its internal storage may change to accommodate more list elements. When your code increases the size of an ArrayStringList object’s internal array storage, you should actively avoid: i) increasing the array size by one; and ii) doubling the size of the array.

    Increasing by one is wasteful as it requires making a new array and copying over all elements every time an item is added. Doubling the size of the array may be wasteful at large sizes as there may be many indices that contain null. Somewhere in between is more reasonable (increasing by 50%? increasing by 25%?

    We will leave the details up to you). Furthermore, you should not set the initial array size to zero or to the largest number that is allowed.

  • There is a requirement related to this class’s storage included in the Non-Functional Requirements.

Dependencies

The ArrayStringList class depends on your BaseStringList class as well as some classes that we have included in cs1302-str-list.jar.

Class / Interface

Description

StringList

An ADT / interface for a sequence of references to non-empty String objects.

You do not have access to the source code for the classes and interfaces in that Java ARchive (JAR) file; however, API documentation for those classes is provided here.

The compilation instructions that we provide below will ensure that these dependencies are available on the classpath so that the compiler can find them.

How to Compile

To compile ArrayStringList.java, execute the following command while directly inside the cs1302-str-list directory:

javac -Werror -g \
    -cp bin:lib/cs1302-str-list.jar -d bin \
    src/cs1302/p2/ArrayStringList.java
cs1302.p2.LinkedStringList
Starter Code

The cs1302.p2.LinkedStringList class is one of the classes that you are responsible for implementing and testing. A partially implemented version of this file is included in the starter code. It is your responsibility to ensure that it is placed under src and named correctly based on the information provided below.

Table 2.10 Starter Code for cs1302.p2.LinkedStringList

Item

Description

Source

src/cs1302/p2/LinkedStringList.java

FQN

cs1302.p2.LinkedStringList

Package Name

cs1302.p2

Simple Name

LinkedStringList

UML Diagrams

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!BASESTRINGLIST
!includesub cs1302-str-list.puml!LINKEDSTRINGLIST

BaseStringList .up.|> StringList : implements
LinkedStringList -up-|> BaseStringList : extends

Fig. 2.15 UML Diagram …

!includesub cs1302-str-list.puml!STYLE
!includesub cs1302-str-list.puml!STRINGLIST
!includesub cs1302-str-list.puml!BASESTRINGLIST_DETAILS
!includesub cs1302-str-list.puml!LINKEDSTRINGLIST_DETAILS

BaseStringList .up.|> StringList : implements
LinkedStringList -up-|> BaseStringList : extends

Fig. 2.16 UML Diagram …

Class Design

Create the LinkedStringList class such that it properly extends BaseStringList and fully implements the StringList interface with additional requirements listed below.

  • You must explicitly define and document a default constructor for this class. The initial size of a LinkedStringList is 0 regardless of the list’s underlying storage — remember, the list’s internal storage and the list itself are two different things. Here is the signature:

    public LinkedStringList() {
    
  • There is a requirement related to this class’s storage included in the Non-Functional Requirements.

Dependencies

The LinkedStringList class depends on your BaseStringList class as well as some classes that we have included in cs1302-str-list.jar.

Class / Interface

Description

StringList

An ADT / interface for a sequence of references to non-empty String objects.

Node

A node for an item in a linked list data structure.

You do not have access to the source code for the classes and interfaces in that Java ARchive (JAR) file; however, API documentation for those classes is provided here.

The compilation instructions that we provide below will ensure that these dependencies are available on the classpath so that the compiler can find them.

How to Compile

To compile LinkedStringList.java, execute the following command while directly inside the cs1302-str-list directory:

javac -Werror -g \
    -cp bin:lib/cs1302-str-list.jar -d bin \
    src/cs1302/p2/LinkedStringList.java
cs1302.p2.StringListTester
Starter Code

The cs1302.test.StringListTester class is one of the classes that you are responsible for updating while working on this project.

Table 2.11 Starter Code for cs1302.test.StringListTester

Item

Description

Source

src/cs1302/test/StringListTester.java

FQN

cs1302.test.StringListTester

Package Name

cs1302.test

Simple Name

StringListTester

UML Diagrams

Please refer to the Testing Setup section provided earlier for more information about how the cs1302.test.StringListTester class is structured, including one or more UML diagrams that show how it relates to the other files in the project.

Class Design

You are responsible for implementing test cases to test your ArrayStringList and LinkedStringList. There are a few examples of test methods already provided for you in cs1302.test.StringListTester, but you will add more as you work through the Project Checklist.

Dependencies

The LinkedStringList class depends on your BaseStringList class as well as some classes that we have included in cs1302-str-list.jar.

Class / Interface

Description

StringList

An ADT / interface for a sequence of references to non-empty String objects.

OracleStringList

An oracle implementation of the StringList interface.

You do not have access to the source code for the classes and interfaces in that Java ARchive (JAR) file; however, API documentation for those classes is provided here.

The compilation instructions that we provide below will ensure that these dependencies are available on the classpath so that the compiler can find them.

How to Compile

To compile ListTester.java, execute the following command while directly inside the cs1302-str-list directory:

javac -Werror -g \
    -cp bin:lib/cs1302-str-list.jar -d bin \
    src/cs1302/test/ListTester.java
Hidden Test Cases (100 points)

The functional aspects of this project will be graded using unit tests, none of which will be made available before the project deadline. You are expected to test your implementations yourself via interface polymorphism in your StringListTester.java file.

2.6. Non-Functional Requirements

A non-functional requirement specifies criteria that can be used to judge your submission independently from its function or behavior. If functional requirements describe what your submission should do, then the non-functional requirements describe how your submission is supposed to be. If your submission does not satisfy a non-functional requirement listed in this section, then the requirement’s point total is deducted from your submission grade.

Missing Parts (45 points)

You are expected to submit all three parts of this project as described elsewhere in this document. 15 points will be subtracted from your earned point total for each missing part, up to a maximum deduction of 45 points.

Environment and Structure (100 points)

This project must compile and run correctly on Odin using the specific version of Java that is enabled by the CSCI 1302 shell profile, and your directory structure and package structure should match the structure of the starter code.

  • The location of the default package for source code should be a direct sub-directory of cs1302-str-list called src.

    • The only .java files that you should include are BaseStringList.java, ArrayStringList.java, LinkedStringList.java, and StringListTester.java (as well as the .java files for any child classes of StringListTester that you create, if applicable).

    • The BaseStringList.java, ArrayStringList.java, LinkedStringList.java, and StringListTester.java files (as well as the .java files for any child classes of StringListTester that you create, if applicable) are expected to compile without any errors or warnings on Odin using the commands provided in the compilation instructions that are included elsewhere in this document for the BaseStringList, |asl|_, |lsl|_, and cs1302.test.StringListTester classes, respectively.

  • The location of the default package for compiled code should be a sub-directory of cs1302-str-list called bin.

    • If you include compiled code with your submission, then it will be ignored. Graders are instructed to recompile your submission on Odin code before testing your submission.

  • The location of your generated API documentation website files should be a sub-directory of cs1302-str-list called doc.

If a problem is encountered for your submission that is explicitly described above, then 100 points will be subtracted from your earned point total; however, if the problem is compilation-related or structure-related and NOT explicitly described above, then it will be handled on an individual basis.

Code Style (20 points)

Every .java file that you include as part of your submission for this project must be in valid style as defined in the CS1302 Code Style Guide. All of the individual code style guidelines listed in the style guide document are considered for this requirement.

If check1302 on Odin reports any style violations for your submission, then 5 points will be subtracted from your earned point total for each violation, up to a maximum deduction of 20 points.

The check1302 command is one of the the last actions performed by the the compile.sh script included in the project’s starter code.

API Documentation Website (5 points)

Generate the API documentation website for all of the code in the cs1302.test and cs1302.p2 packages into a directory named doc directly inside your cs1302-str-list directory, then host the documentation on Odin using cs1302-str-list-doc as the name for your symbolic link. The command to do this is already provided to you in the compile.sh script that is included in the project’s starter code.

To host the API documentation website so that it accessible via your Webwork URL, create a symbolic link to your project’s doc directory at ~/public_html/cs1302-str-list-doc using the ln command by adapting the instructions provided here. You only need to create the symbolic link once, assuming you create it correctly.

If your doc directory is missing OR does not contain the appropriate files, then 5 points will be subtracted from your earned point total. This will be checked for each part, so make sure to double check your doc directory and the generated website to make sure they are up to date prior to submitting each part of the project.

SUBMISSION.md (5 points)

Modify the file named SUBMISSION.md inside the cs1302-str-list directory to include the following information:

  1. Your name and UGA ID number; and

  2. The full link to the API documentation website that you generated and hosted to satisfy the related non-functional requirement stated earlier.

Here is an example of what the SUBMISSION.md file looks like in the starter code:

Sally Smith (811-000-999)
https://webwork.cs.uga.edu/~user/cs1302-str-list-doc

Be sure to modify the contents of SUBMISSION.md with your information! Although the file extension is .md, the SUBMISSION.md file is just a plain text file that you can edit with a text editor like Emacs.

If your SUBMISSION.md file is missing OR does not contain the appropriate information, then 5 points will be subtracted from your earned point total. This will be checked for each part, so make sure to double check your SUBMISSION.md file prior to submitting each part of the project.

Git Commit Log (15 points)

The files in your project submission must be under version and fully committed using Git, and your Git commit log should indicate progress since the project was assigned or since the last part was due, whichever is more recent.

Each part of the project requires you to make several commits, so this shouldn’t be a problem so long as you are following the instructions in the Project Checklist.

If no such progress is indicated via your commit log, then 5 points will be subtracted from your earned point total for each applicable part, up to a maximum deduction of 15 points.

ArrayStringList Storage (100 points)

You must use a basic Java array for this class’s storage. The initial size of the array does not have to be the same size as the initial size of the list. Whenever the size of the list is about to exceed the size of its array, the list should dynamically allocate a new array of a larger size and copy the contents over — please consider writing and documenting a private support method to do this. If you use Java’s java.util.ArrayList class or something similar (e.g., a class that implements java.util.Collection), then that will result in an immediate violation of this non-functional requirement, regardless of any use of a regular array elsewhere in the class. This requirement also prohibits any use of third-party implementations of list or list-like interfaces.

LinkedStringList Storage (100 points)

You must use a sequence of Node objects for this class’s storage. Unlike the array-based implementation in ArrayStringList, this type of storage is not limited to the number of elements that can fit into an array (because there is no underlying array). Instead, it’s limited only by the available memory for the Java program using the LinkedStringList object. If you use Java’s java.util.LinkedList class or something similar (e.g., a class that implements java.util.Collection), then that will result in an immediate violation of this non-functional requirement, regardless of any use of any Node objects elsewhere in the class. This requirement also prohibits any use of third-party implementations of list or list-like interfaces.

No Implementation Dependencies (100 points)

You are not permitted to use one implementation of the StringList interface in another implementation. For example, you cannot use the ArrayStringList class inside of your LinkedStringList class or vice versa. Additionally, BaseStringList cannot depend on either of the StringList implementations; however, it can (and should) depend on the StringList interface itself. If you have any questions about this, then please ask your instructor.

You can check this using the jdeps tool. Inspect the output of the command below after everything is compiled. You do not want to see ArrayStringList pointing to LinkedStringList or vice-versa.

jdeps -v -cp lib/cs1302-str-list.jar bin
No java.util.Arrays Dependencies (or similar; 100 points)

You are also NOT allowed to use the java.util.Arrays class. You can also check for the presence of this dependency using jdeps as described in an earlier requirement — you don’t want to see java.util.Arrays anywhere in the output. The System.arraycopy and the array’s clone method are also not allowed for similar reasons. You can use C-s and C-r in Emacs to see if your files contain these methods.

2.7. Submission Instructions

You will submit each part of your project on Odin. Before you submit each part, make sure that your project files are located in a directory called cs1302-str-list. If you followed the instructions provided earlier in the Getting Started dropdown to download the project’s starter code, then cs1302-str-list is already your directory name.

How to Submit

To submit a specific part of the project, first change into the parent of your project directory (i.e., one directory above it), then complete the steps below.

  1. Ensure that all of the .java files in your project compile without any errors or warnings on Odin using the compile commands included in the compile.sh script that is included in the project’s starter code. This script also checks your .java files for code style violations using the check1302 command, although you can still run check1302 src manually.

    Warning

    If there are style violations, then fix them, recompile, and retest your code! Retesting is important to ensure that you do not accidentally break your code when fixing a style issue.

  2. Ensure that you have generated and hosted the API documentation website for your code, as described in the related non-functional requirement.

    Warning

    You only need to create the symbolic link to your project’s doc directory at ~/public_html/cs1302-p2-doc once using the ln command to host the website. Assuming that the symbolic link was created correctly, you do not need to create it again; however, you must regenerate the website files under doc using the appropriate javadoc command to update the contents of that website.

  3. Ensure that your SUBMISSION.md file is up to date, as described in the related non-functional requirement.

  4. Ensure that your project’s code is fully committed using Git. You can use the git status command to determine if the local copy of your repository has any changes that need to be committed (or confirm that everything is good), then use the git add and git commit commands to stage and commit changes, as needed.

    What to look for when using git status

    If your copy of the project is fully committed, then git status should inform your that there is nothing commit:

    git status
    
    On branch main
    ...
    nothing to commit, working tree clean
    

    You do not have permission to publish your local commits to the book author’s copy of the repository at origin/main, so please disregard any suggestion from Git to use git push when working on this project.

    git status
    
    On branch main
    Your branch is ahead of 'origin/master' by ?? commits.
      (use "git push" to publish your local commits)
    ...
    

    If you add any new .java files (e.g., if you setup separate tester classes as described in the comments inside StringListTester.java, then they will not be tracked by Git at first. The git status command will let you know this and give you the command to use in order to start tracking them and add include them on the stage for your next commit.

    git status
    
    On branch main
    ...
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            source/cs1302/test/ArrayStringListTester.java
            source/cs1302/test/OracleStringListTester.java
            source/cs1302/test/LinkedStringListTester.java
    
  5. Once you are certain that the code included in your project compiles, has no code style violations, includes both an up-to-date doc directory and SUBMISSION.md file, and is fully committed using Git, then you can submit your work using the following command, replacing N with the specific part of the project you are submitting:

    submit1302 cs1302-str-list partN
    

    Warning

    Do NOT literally type partN; instead, be sure to replace N with the specific part of the project you are submitting! For example, use part1 when submitting Part 1.

  6. Inspect the output of the last command to verify that your project was submitted. Your cs1302-str-list directory should now contain a receipt file that starts with rec. The exact name of the receipt file may vary, depending on the part of the project that you are submitting.

If you have any problems submitting your project then please contact your instructor as soon as possible; however, doing this the day or night the project is due is probably not the best idea.

2.8. Frequently Asked Questions

What is a Java ARchive (JAR) file?

In Java, .jar files are Java™ Archive (JAR) files that bundle multiple files into a single compressed file. Typically a JAR file contains the package directories and .class files for a library. This is just like the bin directory that you are used to, except it is all bundled into a single file.

How can I test that exception was thrown?

In this project, you are tasked with making sure that exceptions are thrown from your method overrides in certain situations based on each method’s API documentation. When testing your methods, you will want to make sure that one of the things you check is that your methods actually do, in fact, throw those exceptions when they are expected to per the API documentation.

An example of a test method you might write to test whether your add(int, String) method throws an IndexOutOfBoundsException when a negative value is supplied for the index parameter is provided below in Listing 2.27.

Listing 2.27 A test method to check that add(int, String) throws an IndexOutOfBoundsException when a negative value is supplied for the index parameter.
public void testScenario4() {
    try {
        StringList list = this.newStringList();
        list.add(-1, "a");
        throw new AssertionError(
            "add(int, String): no exception thrown, but IOOBE expected"
        );
    } catch (IndexOutOfBoundsException ioobe) {
        System.out.println("add(int, String): IOOBE thrown as expected");
    } catch (Throwable cause) {
        throw new AssertionError(
            String.format(
                "add(int, String): %s thrown, but IOOBE expected",
                cause.getClass().getName()
            ),
            cause
        );
    } // cause
} // testScenario4

We recommend that you further break up your test code into methods in order to reduce the redundancy you see in the example above. Your test code does not need to look exactly like the test code what we provide, but an illustrative example is provided below in Listing 2.28 to help you get started with this idea.

Listing 2.28 A test method to check that add(int, String) throws an IndexOutOfBoundsException when a negative value is supplied for the index parameter. In this example, the parts related to passing or failing the test are factored out into reusable static methods that to help make the test code more readable. You will need to include proper Javadoc comments if you add these static methods to your tester class.
private static void pass(String message, Object... args) {
    System.out.printf(message, args);
} // pass

private static void fail(String message, Object... args) {
    String formatted = String.format(message, args);
    throw new AssertionError(formatted);
} // fail

private static void failFromException(Throwable cause, String message, Object... args) {
    String formatted = String.format(message, args);
    throw new AssertionError(formatted, cause);
} // failFromException

public void testScenario4() {
    try {
        StringList list = this.newStringList();
        list.add(-1, "a");
        StringListTester.fail("add(int, String): no exception thrown, but IOOBE expected");
    } catch (IndexOutOfBoundsException ioobe) {
        StringListTester.pass("add(int, String): IOOBE thrown as expected");
    } catch (Throwable cause) {
        StringListTester.failFromException(
             cause,
             "add(int, String): %s thrown, but IOOBE expected",
             cause.getClass().getName()
        );
    } // catch
} // testScenario4
Why doesn’t inheritDoc seem to work?

The {@inheritDoc} tag does not work because the javadoc tool requires the source code in order to automatically pull the text of comments from supertypes when applicable. We did not provide you with the source code for the interface, so this is working as intended.

Tip

Do NOT manually copy the entire comment and parameter details from the API website. Instead, include a summary sentence and {@inheritDoc} to make it clear to readers of the source code that your intent is to inherit the documentation. An example of this can be found in the style guide, here.