EECS2030Z Test 2
PRACTICE
Question 1
Implement the utility
class described by this API .
You do not have to include javadoc comments.
package test2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Utility2P {
private Utility2P() {
}
public static String hello(String name) {
return "Hello, " + name;
}
public static String toString(List<Character> t) {
if (t.isEmpty()) {
throw new IllegalArgumentException();
}
String s = "";
for (Character c : t) {
s += c;
}
return s;
}
public static List<Character> shuffle(List<Character> t) {
int n = t.size();
List<Character> result = new ArrayList<>();
for (int i = 0; i < n / 2; i++) {
result.add(t.get(i));
result.add(t.get(i + n / 2));
}
return result;
}
}
Question 1
Starting with the code given below, implement the constructors for the
class described by this API . Use constructor chaining where
possible when implementing your constructors.
You do not have to include javadoc comments.
package test2;
import java.awt.Color;
public class Circle {
/**
* The radius of the circle.
*/
private double radius;
/**
* The color of the circle.
*/
private Color color;
}
package test2;
import java.awt.Color;
public class Circle {
/**
* The radius of the circle.
*/
private double radius;
/**
* The color of the circle.
*/
private Color color;
public Circle() {
this(1.0, Color.BLUE);
}
public Circle(double radius, Color color) {
if (radius < 0.0) {
throw new IllegalArgumentException();
}
this.radius = radius;
this.color = color;
}
Question 3
Create a text file named answers.txt
(use File ->New ->
Untitled text file in eclipse). Type your answer
to the following question in the text file.
A.
Consider the field Utility2P.TEST_VERSION
. What does the
keyword final
mean when used to modify a field?
final
when used to modify a field means that the field can
only be assigned a value once; it does not necessarily mean that the field
is a constant.
B.
Suppose a client writes a main
method that includes the
following two lines of Java code:
List<Character> aList = Arrays.asList('g', 'o', 'o', 'd', 'b', 'y', 'e');
Utility2P.shuffle(aList);
The first line of code creates the list ['g', 'o', 'o', 'd', 'b', 'y', 'e']
,
and the second line of code calls the shuffle
method from Question 1.
The memory diagram illustrating the state of memory for the two lines of code
is shown below.
What suitable values of a, b, and c would complete the memory diagram?
---------------------
| main method |
---------------------
aList 100| a? |
---------------------
| |
| |
---------------------
b? | List object |
---------------------
| |
| |
---------------------
| Utility2P.shuffle |
---------------------
t 500| c? |
---------------------
The address of the List object can be any positive integer value greater
than 100 and less than 500; let's pick the value 300. Then we have:
b = 300
a = 300a
c = 300a
In other words, aList
and the parameter t
(from shuffle
) both refer to the same
list object which resides
at address 300.
C.
Consider the method Utility2P.hello(String)
from Question 1.
What precondition does the method have? Suppose that as the implementer,
you wanted to remove the precondition from Utility2P.hello(String)
;
how could you change your implementation to remove the precondition?
The precondition is stated in the documentation for the parameter
name
: name
must not be equal to null
.
Removing the precondition means that the implementer is willing to account for
the case that name == null
; this usually means that the implementation
will first check if name == null
and then do the appropriate thing
to satisfy the postconditions of the methods.
For example, the implementer might
choose to state that the postcondition when name == null
is to
return the string "Hello, stranger"
.
D.
Provide 3 test cases for the method Utility2P.toString(List<Character>)
.
Make sure that each test case tests a different feature of the method (i.e., don't
provide 3 test cases that all check if the correct string was returned).
For each test case, provide a one sentence explanation of what the test case
is testing.
A test case must state what inputs will be used to run the method, and what
the expected results are of running the method with the stated inputs. The question
also asks to test different features of the method so you use test cases that
test if the correct string is returned, if an exception is thrown when the
input list is empty, if an exception is not thrown when the
input list is not empty, and if the input list is not modified. It might
also be useful to test a boundary case which for this method would be
a list of size 1. Five possible test case examples would be:
input: ['a', 'b', 'c']
expected result: string "abc" is returned
explanation: Tests if the expected string is returned for a typical input.
input: the empty list
expected result: IllegalArgumentException is thrown
explanation: Tests if an exception is thrown for an empty list.
input: ['a', 'b', 'c']
expected result: no exception is thrown
explanation: Tests if no exception is thrown for a non-empty list.
input: ['a', 'b', 'c']
expected result: input list is equal to ['a', 'b', 'c'] (after the method is run)
explanation: Tests if the input list remains unchanged.
input: ['a']
expected result: string "a" is returned
explanation: Tests if the expected string is returned for a boundary case.
E.
Consider the following implementation of equals(Object)
for the Circle
class in Question 2:
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
Circle other = (Circle) obj;
if (!this.color.equals(other.color)) {
return false;
}
if (Double.doubleToLongBits(this.radius) != Double
.doubleToLongBits(other.radius)) {
return false;
}
return true;
}
What is missing from the implementation shown above compared to how
equals
is normally implemented? Explain whether or not
the implementation shown above still satisfies the equals contract.
The first thing most equals implementations do is check that this == obj
:
if (this == obj) { return true; }
The implementation still satisfies the equals contract because the only thing
that the missing if statement does is check if this
and obj
are references to the same object; in other words, it ensures that statements like
x.equals(x)
returns true
. The given implementation
still ensures that x.equals(x)
returns true
because it returns true
when the color and radius of this
circle are equal to the color and radius of the circle obj
.