The goals of this project are to re-familiarize yourselves with common ADTs, to begin thinking about implementation questions, to underscore the distinction between abstract and concrete, and, generally, to review writing classes in Java.
This project typifies how projects will tend to be like in this course (except that subsequent projects will tend to be more difficult): Implement a data structure or algorithm (or series of data structures and algorithms), testing them with given test cases.
This project is found in the book as Project 2.1 on page 127, but I'll give you some guidance here as well.
Copy the given code for this project from
~tvandrun/Public/cs345/adt-review
and make
an Eclipse project for it.
If you find yourself needing detailed instructions,
you'll find this project used as the example in
the general project guide
for this course.
I won't be giving instructions on project set-up
from this point on.
This project's packages typify how most of this
course's project will be structured.
It has three packages, adt
for the interfaces
of the ADTs used in the project---in this case, the "canonical"
ADTs;
impl
for the classes that implement the ADTs
with specific strategies, some of which are stubs for you to complete;
and test
for the JUnit tests.
(Some future projects will also have packages alg
and exper
for classes containing static methods implementing algorithms
and classes containing experiments, respectively.)
In this project, most of the implementations are wrappers that use another ADT as their underlying implementation, somewhat like the Adapter pattern.
ArrayMap
, an implementation of the map ADT
that uses an array (or arrays) as its implementation strategy.
This one is not a wrapper for another implementation but
a class to be written "from scratch", except that
I've already given you part of it.
MapSet
, an implementation of the set ADT
that uses a map as its implementation strategy.
You will need to write this as a wrapper for a map.
In theory this could use any map implementation, but it will be
tested using your ArrayMap
.
ListSet
, and implementation of the set ADT
that uses a list as its implementation strategy.
In theory this could use any list, but it will be testing using
the provided LinkedList
.
MapList
, an implementation of the list ADT
that uses a map as its implementation strategy.
You will need to write this as a wrapper for a map.
In theory this could use any map implementation, but it will be
tested using your ArrayMap
.
ListBag
, an implementation of the bag ADT
that uses a list as its implementation strategy.
You will need to write this as a wrapper for a list.
In theory this could use any list implementation, but it will be
tested using your MapList
.
ListQueue
, an implementation of the queue ADT
that uses a list as its implementation strategy.
This is written for you, but it will be
tested using your MapList
(which, in turn, makes it essentially as test for MapList
).
ListStack
, an implementation of the stack ADT
that uses a list as its implementation strategy.
This is written for you, but it will be
tested using your MapList
(which, in turn, makes it essentially as test for MapList
).
Note that the naming convention for classes in the impl
package are XY
where Y
is the ADT being
implemented and X
is the strategy being used, which
could be either a concrete data structure or another ADT.
Thus ArrayMap
is a map built using an array inside,
and MapList
is a list using a map (in theory, any map)
inside.
The classes you are given to complete already have instance variables. You may add more instance variables (in fact, in some of the classes you will need to add at least one instance variable), but you may not change the basic implementation strategy, described in each task.
In none of these tasks (or any other project in this course) should you in any way change the public interface of the classes, including the signatures of their constructors, and do not change any of the classes that you are not told to finish (except perhaps for debugging purposes, but be careful and be able to undo those changes). You will not be turning in the whole project but only the classes you are told to modify. Your submission will be graded based on how it works with the original forms of the other classes in the codebase.
ArrayMap
Your first task is to finish
ArrayMap
.
For convenience I have provided a nested class for key/value pairs
and declared an instance variable for an array of these.
Also for convenience I have written the constructor to make an
initial array and given a helper method to make the array grow.
You may modify this as long as it retains the basic strategy of using
an array (or arrays).
For example, you may choose to have two parallel arrays (one for keys,
one for values) instead of an array of pairs---but you may not
use ArrayList
or any other off-the-shelf component,
and you may not use a linked-list approach.
You can test your class using AMTest
;
the code test cases themselves can be found in the parent class
MapTest
.
I recommend inspecting the tests to figure out which correspond to
which Map
methods and use that to determine
a sensible order in which to implement the methods in
ArrayMap
and test as you go.
(You should always be looking for new test cases at add.)
Things to watch out for:
equals()
method,
not using ==
.
Make sure you understand the difference!
put()
with a key that already has a value
associated with it should overwrite the old value.
This should not add another association with the same key.
MapSet
Next finish MapSet
.
You will first need to figure out how a map can be used to implement
a set, but once you have done that this task is "easy."
Keep in mind that although the JUnit test cases will test
MapSet
by giving it an instance of
your ArrayMap
from last time, the implementation
of MapSet
should not depend on the implementation details
of ArrayMap
---it should
depend only on the Map
interface.
Your implementation must use a Map
as its
underlying container (already present in the given instance variable
internal
, but you may add primitive-typed
instance variables
if necessary.
(Hint: The second type parameter to Map
in the
declaration of internal
is String
.
That was largely an arbitrary choice.
Almost any class would do.)
Test using MSTest
;
the actual tests are in the parent class MapTest
.
ListSet
Finish ListSet
; similar rules apply.
Test using LSetTest
.
MapList
Finish MapList
; similar rules apply.
(Hint: Notice that the key type of internal
is int
.
Think about how a map can be thought of as a generalization of a list.)
Test using MLTest
, a child class of ListTest
.
Things to watch out for:
MapList
iterator
to depend on the iterator of the internal map.
The MapList
iterator must return elements in index order,
but there is no guarantee on what order the iterator of the internal
map will return keys.
ListBag
Finish ListBag
; similar rules apply.
This will be tested using a MapList
which in turn uses
an ArrayMap
.
See the given Bag
interface for details of the
specification.
Test using LBTest
, a child class of
BagTest
.
ListQueue
and ListStack
The last two are already given to you, but you should make sure that
LQTest
and LSTest
run correctly
using your MapList
as the underlying implementations
for these two classes.
Copy the files you modified (ArrayMap
,
MapSet
, ListSet
, MapList
,
and ListBag
) to your turn-in folder
/cslab/class/cs345/(your id)/adt-review
.
To keep up with the course, this should be finished by Feb 3.