Due: 10pm on Wednesday, May 27.
In this assignment you’ll learn about an important built-in Java interface,
practice with Java lists, and work on understanding how to throw
exceptions.
On this assignment, you can share ideas for tests with other students in
the course and on Piazza, but you cannot share code with anyone other than
the course staff. If you want to share information about tests, describe them
or use shorthand notation like “try passing in the list {1, 2, 3}
and you
should expect X as an answer” rather than writing out Java code for it.
Submission checklist:
CompareLists.java
, submitted to the pa8
assignment:
[ ]
Implementations of Comparator
classes[ ]
Sufficient tests for each Comparator
class you wrote[ ]
Implementations of array/List
methods[ ]
Sufficient tests for each method[ ]
PDF submission of memory diagram for exception, submitted to the
pa8-stacktrace
assignmentStarter code is available here (includes relevant imports):
https://github.com/ucsd-cse11-s20/pa8-starter
CompareLists.java
. Make sure to also take a look at the tips and tricks section of the writeup for a convenient way to create Lists in Java!Comparator
class for testing?”
{1,2, 2, 3, 4}
and {}
in order?”
newArrayList.add("Hello world");
XXXCompare
classes return? Some are not explicitly said in the description.
class CompareDoubles
provided right before the Comparator section.Comparator
section of the PA and a single method for List Methods. I want to submit to gradescope but my code is not compiling.
checkExpect
for exception tests.
checkException
method instead.The
Comparator
interface in Java describes operations that compare two values of the same
type. A Comparator
’s compare
method should return a negative number if
the first argument is less than the second, 0 if they are equal, and a
positive number if the first argument is greater than the second.
For example, a Comparator
that compares two Double
s we could write as:
class CompareDoubles implements Comparator<Double> {
public int compare(Double n, Double m) {
if(n > m) { return 1; }
else if(m > n) { return -1; }
else { return 0; }
}
}
All of your code will go into a single file CompareLists.java
.
First, write the following implementations of the Comparator
interface. You
can write them all in the file CompareLists.java
.
PointCompare
that implements Comparator<Point>
that compares points by the following process
y
coordinate is smaller than the other point’s
y
coordinate, it is smaller; if y
is greater, it’s greater.y
coordinates are the same, if the first point’s x
coordinate is smaller, it is smaller, if greater, the first point is
greater.0
PointDistanceCompare
that implements Comparator<Point>
for Point
s that compares the points’ distance from (0, 0)
. If the first
point’s distance is closer to 0, it’s smaller, if the distances are equal,
the points are equal, and if the distance is further from 0, the point is
larger.Write a class StringCompare
that implements Comparator<String>
that uses the
compareTo
method on strings for comparison and returns the result of
compareTo
directly.
StringLengthCompare
that implements Comparator<String>
that compares String
s
by length, where shorter strings are “smaller”.BooleanCompare
that implements Comparator<Boolean>
where
true
is greater than false
.Write at least four checkExpect
tests for each Comparator
’s compare
method to demonstrate that they work correctly (so at least 20 tests total).
In this part of the assignment, you’ll write several generic List
methods that make use of the Comparator
interface. Write these all in a
class named CompareLists
in CompareLists.java
.
minimum
that takes a List<E>
and a
Comparator<E>
and returns the smallest element in the list according the
comparator, or null
if the list is empty. Assume there are no null
elements in the list.minimum
that takes an E[]
(an
array of E
) and a Comparator<E>
and returns the smallest element in the
array according the comparator, or null
if the array is empty. Assume there
are no null
elements in the array.greaterThan
that takes a List<E>
, a
Comparator<E>
, and an element E
, and returns a new List<E>
containing just the elements that are larger than the given element
according to the given comparator. Assume there are no null
elements in the
array.inOrder
that takes a List<E>
and a
Comparator<E>
and returns true
if the elements in the array list are in
increasing order according to the comparator, and false
otherwise. If any
of the elements in the list are null
, throw an IllegalArgumentException
with a message that says "null value in list"
.inOrder
that takes an E[]
(an
array of E
) and a Comparator<E>
and returns true
if the elements in the
array list are in increasing order according to the comparator, and false
otherwise. If any of the elements in the list are null
, throw an
IllegalArgumentException
with a message that says "null value in array"
.merge
that takes a Comparator<E>
and two
List<E>
, each of which is in increasing order according to the given
comparator. It should return a new List<E>
containing all the
elements from both lists in increasing order. If any of the elements in
either list are null
, throw an IllegalArgumentException
with a message
that says "null value in first list"
if it came from the first one, and
"null value in second list"
if it came from the second one.Write at least this many tests:
checkExpect
test for three of the
comparators you wrote in the first part (so you should write 18 total tests
for this task). You should write more than this to be confident that your
methods work correctly, but this amount will make sure you have some basic
coverage.For each method that has throwing an exception in its description, at least one of the tests should throw an exception, and you should test for it. Tests for exceptions look like this:
t.checkException(new IllegalArgumentException("message goes here"),
this, "inOrder", aTestList)
The constructed exception is the expected exception value. The this
,
"inOrder"
, and aTestList
describe a method call like
this.inOrder(aTestList)
in a way that the tester library can call the
method while checking for the required exception.
Choose one of your methods that throws an exception. Make a method call that triggers the exception so that the exception you wrote gets reported at the command line and you can see the stack trace.
Take a screen shot of the stack trace.
Draw a picture of the stack and heap at the time the exception was thrown. You can use the style from class/the notes with boxes for method calls and objects/arrays/lists. Put your drawing in the document.
Then, include screenshots of the methods and method calls from your code that are reported in the stack trace.
You can use this document as a template:
Submit your code to pa8
, and submit your stack trace diagram and
screenshots as a PDF to pa8-stacktrace
.
All of the methods are specified to use the type List
. List
is an
interface in Java that specifies a number of methods implemented by different
classes, though the most commonly used is ArrayList
. So you can use new
ArrayList
when you need to construct a new list in the body of a method, but
use the List
type for the parameters and return types.
Constructing List
s by using new ArrayList
and then repeated calls to
the add
method can be annoying. Instead, you can use this pattern to create
lists in one line:
List<String> abc = Arrays.asList("a", "b", "c");
This can make writing test data much more pleasant.
Leave time to think through merge
, which takes some careful thought, and
test it thoroughly to make sure you’ve tried it with lists of different
lengths and contents.
Check out the Java documentation on Method
References and the video
in this course on lambda expressions for ways to create Comparator
s
with less code!