EECS1030Z Test 3

Wednesday February 25, 2015, 14:30-15:45
Lab 02
Version C


Programming question

Implement the Range class having the API shown here. A skeleton can be found here.

package test3;

/**
 * A class that represents a range of values on the real number line. A range
 * has two properties: a <code>minimum</code> value and a <code>maximum</code>
 * value. Range objects always ensure that the following class invariant is
 * true:
 * 
 * <p>
 * <code>minimum <= maximum</code>
 * 
 * <p>
 * The constructors of the class are responsible for ensuring that the above
 * class invariant is always true.
 * 
 * @author EECS1030Z_2014_15W
 * 
 */
public class Range {
  private static double DEFAULT_MIN = 0;
  private static double DEFAULT_MAX = 100;

  private double min;
  private double max;

  /**
   * Create a range with minimum value 0 and a maximum value 100.
   */
  public Range() {
    this(Range.DEFAULT_MIN, Range.DEFAULT_MAX);
  }

  /**
   * Create a range with the specified minimum and maximum values.
   * 
   * @param min
   *          the minimum value of the range
   * @param max
   *          the maximum value of the range
   * @throws IllegalArgumentException
   *           if <code>min > max</code>
   */
  public Range(double min, double max) {
    if (min > max) {
      throw new IllegalArgumentException("min > max");
    }
    this.min = min;
    this.max = max;
  }

  /**
   * Returns the minimum value of the range
   * 
   * @return the minimum value of the range
   */
  public double getMinimum() {
    return this.min;
  }

  /**
   * Returns the maximum value of the range
   * 
   * @return the maximum value of the range
   */
  public double getMaximum() {
    return this.max;
  }

  /**
   * Checks if <code>value</code> is inside this range. A value is considered
   * inside this range if both
   * 
   * <p>
   * <code>value >= minimum</code> and <code>value <= maximum</code>
   * 
   * <p>
   * are true.
   * 
   * @param value
   *          the value to check
   * @return <code>true</code> if <code>value</code> is inside this range,
   *         <code>false</code> otherwise
   */
  public boolean contains(double value) {
    return (value >= this.getMinimum()) && (value <= this.getMaximum());
  }

  /**
   * Checks if this range overlaps with another range. Two ranges overlap if at
   * least one <code>double</code> value is contained by both ranges. For
   * example, the two ranges
   * 
   * <p>
   * <code>[0.1, 0.8]</code> and <code>[0.6, 2.5]</code> overlap because all
   * values between <code>0.6</code> and <code>0.8</code> are contained by both
   * ranges.
   * 
   * <p>
   * The two ranges
   * 
   * <p>
   * <code>[-0.25, 0.33]</code> and <code>[0.33, 1.0]</code> overlap because
   * both ranges contain the value <code>0.33</code>
   * 
   * 
   * @param other
   *          the other range to check
   * @return <code>true</code> if this range overlaps with <code>other</code>,
   *         and <code>false</code> otherwise.
   */
  public boolean overlaps(Range other) {
    return this.contains(other.getMinimum())
        || this.contains(other.getMaximum());
  }

  /**
   * Return a new range that is centered at <code>value</code> and whose total
   * width is <code>width</code>. For example:
   * 
   * <p>
   * <code>Range.centeredAt(10.0, 5.0)</code>
   * 
   * <p>
   * would return the range <code>[7.5, 12.5]</code>.
   * 
   * 
   * @param value
   *          the center of the desired range
   * @param width
   *          the total width of the desired range
   * @pre. <code>width >= 0</code>
   * @return a new <code>Range</code> centered at <code>value</code> and whose
   *         total width is <code>width</code>
   */
  public static Range centeredAt(double value, double width) {
    double half = width / 2;
    return new Range(value - half, value + half);
  }

  /**
   * Returns the string representation of a range. The string contains the
   * minimum and maximum values separated by a comma and space all inside of a
   * pair of square brackets. For example, the string
   * 
   * <p>
   * <code>[-3.14, 3.14]</code>
   * 
   * <p>
   * represents the range whose minimum value is <code>-3.14</code> and whose
   * maximum value is <code>3.14</code>
   * 
   * @return a string representation of the range
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return "[" + this.getMinimum() + ", " + this.getMaximum() + "]";
  }

  /**
   * Returns a hash code for this range.
   * 
   * @return a hash code for this range
   * @see java.lang.Object#hashCode()
   */
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(max);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    temp = Double.doubleToLongBits(min);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
  }

  /**
   * Compares this <code>Range</code> to the specified <code>Object</code>. The
   * result is true if and only if the argument is a <code>Range</code> object
   * having the same minimum and maximum value as this object.
   * 
   * @param obj
   *          the object to compare with
   * @return <code>true</code> if this object is equal to <code>obj</code>;
   *         <code>false</code> otherwise
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    Range other = (Range) obj;
    if (Double.doubleToLongBits(max) != Double.doubleToLongBits(other.max)) {
      return false;
    }
    if (Double.doubleToLongBits(min) != Double.doubleToLongBits(other.min)) {
      return false;
    }
    return true;
  }

}


Other questions

Question 1

What is the purpose of a singleton class?

A. to prevent the client from directly creating an instance of the singleton type
B. to ensure that there is always exactly zero or one instance of the singleton type
C. to ensure that there is exactly one instance for every unique state of the singleton type
D. to replace a utility class with an instance of the singleton class

Question 2

The Range method named centeredAt resembles a constructor in that it returns a reference to a new Range object. Why can it not be a constructor in Range?

A. it does not specify a minimum and maximum value for the range
B. it has a precondition and constructors should not have preconditions
C. the client can use another constructor to achieve the same result
D. it has the same parameter list as another constructor

Question 3

The Range method named centeredAt resembles a constructor in that it returns a reference to a new Range object; what name is given to a method like centeredAt that returns a reference to a newly created object?

Type your answer here: static factory method

Question 4

What is the name of the relationship between the two classes shown in the following UML diagram:



Type your answer here: aggregation

Question 5

As the implementer of Range, list all of the changes that you would make to the Range class so that a client could obtain the number of Range objects that have been created in the client's application?


-add a private static field to maintain the count
-increment the static counter in the constructor(s)
-provide a public static method that returns the count

Question 6

Suppose that we modifed the Range class so that it implemented the interface Comparable<Range>. Consider the following implementation of the method compareTo:

public int compareTo(Range other) {
  if (this.overlaps(other)) {
    return 0;
  }
  if (this.getMaximum() < other.getMinimum()) {
    return -1;
  }
  return 1;
}

Explain whether or not the implementation of compareTo is reasonable.


The implementation is not reasonable because the resulting method is not transitive. Suppose that you have 3 ranges x (0, 5), y (4, 9), and z (10, 15). Then:

x.compareTo(y) == 0 (x overlaps y)
y.compareTo(z) == 0 (y overlaps z)
x.compareTo(z) == -1