CS 5010: Problem Set 10

Out: Monday, 13 November 2017
Due: Monday, 27 November 2017 at 6pm local time

This is an individual assignment. You are not allowed to discuss this problem set with any other person. You are also not allowed to search for or to view any solutions to similar problems that may be available on the World-Wide Web or in other resources that might otherwise have been available to you.

The main purpose of this problem set is to give you practice implementing abstract data types, both mutable and immutable. The problem set will also give you some practice implementing equals(Object), hashCode(), toString(), and iterator() methods.

We will test your program using Java 8, which is the version of Java installed on CCIS Linux machines. You will therefore want to use Java 8 when developing and testing your program.

For these problems, we are giving you the following files:

You must not change those files in any way.

Parts 1 and 2 of this problem set ask you to create two more files named Players.java and Rosters.java. Both of those files must be in the default package. In other words, your Java files should not contain any package declarations.

You are free to create additional files. When we test your submission, we will compile all of the Java files in your set10 directory using the following command:

      javac *.java

You should start by downloading the two files we are giving you, unpacking them into a set10 directory, and pushing that directory to your GitHub repository.

We are giving you a choice of two formats in which to download the files we are giving you. Both of these links will unpack to the same set10 directory containing exactly the same Java files:

Remember that you must follow the design recipe, which is a process, not a list of deliverables.

Be sure to fill out a work session report at the end of each work session. Be sure to report only the hours spent in that work session; do not report the cumulative time. Tell git to add your work session report to the files you will commit, and then commit and push (sync) that report in addition to committing and pushing your entire set10 directory. Do this at the end of every work session.


This problem set asks you to implement two abstract data types, Player and Roster. These ADTs would be useful to the coaches of a team sport as they consider different rosters they might use for an upcoming game. In the NFL, for example, a team's roster can contain up to 53 players, but some of those players may be unavailable because of suspension or injury. On game day, the head coach must designate a smaller roster with no more than 46 players, and coaches routinely consider several of those smaller rosters before deciding which roster to use in the game.

To make it easier to consider several similar rosters, the Roster ADT is immutable. The Player ADT is mutable, however, because an injury, trade, or some other change to a player's status should be propagated immediately to all rosters that use the player.

      // A Player is an object of any class that implements the Player interface.
      //
      // A Player object represents a member of a team.
      // Player objects are mutable because their status can change without
      // changing the identity of the Player.
      // 
      // If p1 and p2 are players, then p1.equals(p2) if and only if
      // p1 and p2 are the same object (i.e. (p1 == p2), p1 and p2
      // have the same name and status, and changing the status of p1
      // necessarily changes the status of p2 in the same way).
      //
      // If p is a player, then p.hashCode() always returns the same
      // value, even after the player's status is changed by calling
      // one of the last three methods listed below.
      //
      // If p1 and p2 are players with distinct names, then
      // p1.toString() is not the same string as p2.toString().
      //
      // Players.make(String name) is a static factory method that returns
      // a player with the given name who is (initially) available.
      
      interface Player {
      
          // Returns the name of this player.
          // Example:
          //     Players.make("Gordon Wayhard").name()  =>  "Gordon Wayhard"
      
          String name ();
      
          // Returns true iff this player is
          //     under contract, and
          //     not injured, and
          //     not suspended
          // Example:
          //     Player gw = Players.make ("Gordon Wayhard");
          //     System.out.println (gw.available());  // prints true
          //     gw.changeInjuryStatus (true);
          //     System.out.println (gw.available());  // prints false
      
          boolean available ();
      
          // Returns true iff this player is under contract (employed).
          // Example:
          //     Player ih = Players.make ("Isaac Homas");
          //     System.out.println (ih.underContract());  // prints true
          //     ih.changeContractStatus (false);
          //     System.out.println (ih.underContract());  // prints false
          //     ih.changeContractStatus (true);
          //     System.out.println (ih.underContract());  // prints true
      
          boolean underContract ();
      
          // Returns true iff this player is injured.
      
          boolean isInjured ();
      
          // Returns true iff this player is suspended.
      
          boolean isSuspended ();
      
          // Changes the underContract() status of this player
          // to the specified boolean.
      
          void changeContractStatus (boolean newStatus);
      
          // Changes the isInjured() status of this player
          // to the specified boolean.
      
          void changeInjuryStatus (boolean newStatus);
      
          // Changes the isSuspended() status of this player
          // to the specified boolean.
      
          void changeSuspendedStatus (boolean newStatus);
      }
      // A Roster is an object of any class that implements the Roster interface.
      //
      // A Roster object represents a set of players.
      //
      // Roster objects are immutable, but all players on a roster
      // have mutable status, which can affect the values returned by
      // the readyCount() and readyRoster() methods.
      //
      // If r1 and r2 are rosters, then r1.equals(r2) if and only if
      // every player on roster r1 is also on roster r2, and
      // every player on roster r2 is also on roster r1.
      //
      // If r is a roster, then r.hashCode() always returns the same
      // value, even if r has some players whose status changes.
      //
      // If r1 and r2 are rosters of different sizes, then
      // r1.toString() is not the same string as r2.toString().
      //
      // Rosters.empty() is a static factory method that returns an
      // empty roster.
      
      import java.util.Iterator;
      
      interface Roster extends Iterable<Player> {
      
          // Returns a roster consisting of the given player together
          // with all players on this roster.
          // Example:
          //     r.with(p).with(p)  =>  r.with(p)
      
          Roster with (Player p);
      
          // Returns a roster consisting of all players on this roster
          // except for the given player.
          // Examples:
          //     Rosters.empty().without(p)  =>  Rosters.empty()
          //     r.without(p).without(p)     =>  r.without(p)
      
          Roster without (Player p);
      
          // Returns true iff the given player is on this roster.
          // Examples:
          //
          //     Rosters.empty().has(p)  =>  false
          //
          // If r is any roster, then
          //
          //     r.with(p).has(p)     =>  true
          //     r.without(p).has(p)  =>  false
      
          boolean has (Player p);
      
          // Returns the number of players on this roster.
          // Examples:
          //
          //     Rosters.empty().size()  =>  0
          //
          // If r is a roster with r.size() == n, and r.has(p) is false, then
          //
          //     r.without(p).size()          =>  n
          //     r.with(p).size()             =>  n+1
          //     r.with(p).with(p).size()     =>  n+1
          //     r.with(p).without(p).size()  =>  n
      
          int size ();
      
          // Returns the number of players on this roster whose current
          // status indicates they are available.
      
          int readyCount ();
      
          // Returns a roster consisting of all players on this roster
          // whose current status indicates they are available.
      
          Roster readyRoster ();
      
          // Returns an iterator that generates each player on this
          // roster exactly once, in alphabetical order by name.
      
          Iterator<Player> iterator ();
      }
You may not change these interfaces in any way, but you may define new interfaces that extend them.
  1. (Player)

    For this first part of Problem Set 10, you will define a public class named Players in a file named Players.java. That class will define a public static factory method named make that takes a String as its one and only argument and returns a Player whose name is the given string.

  2. (Roster)

    For this second part of Problem Set 10, you will define a public class named Rosters in a file named Rosters.java. That class will define a public static factory method named empty that takes no arguments and returns an empty roster.

    HINT: iterator() methods are often implemented by creating an object of some predefined class and then creating the desired iterator by calling that object's iterator method.