Computer Science 15-110, Spring 2010
Class Notes: Writing Classes
Writing Classes
// This is an excerpt of the Fraction class from
// "Getting Started with Writing Classes", adapted here
// to be sortable (by implementing the Comparable interface).
import java.util.*;
class Fraction implements Comparable {
public static void main(String[] args) {
Fraction[] a = { new Fraction(3,4), new Fraction(1,3), new Fraction(2,3),
new Fraction(5,12),new Fraction(7,12), new Fraction(1,2) };
System.out.println(Arrays.toString(a));
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}
// compareTo method (for Comparable interface)
public int compareTo(Object object) {
Fraction that = (Fraction)object;
return (int)Math.signum(this.getDoubleValue() - that.getDoubleValue());
}
public double getDoubleValue() {
return 1.0 * this.num / this.den;
}
// Instance variables
private int num, den;
public Fraction(int num, int den) {
// handle the sign -- only the num can be negative
if (den < 0) {
den = -den;
num = -num;
}
// and assign to the instance variables
this.num = num;
this.den = den;
// reduce them
int gcd = gcd(num, den);
if (gcd > 0) {
this.num /= gcd;
this.den /= gcd;
}
}
private static int gcd(int x, int y) {
x = Math.abs(x);
y = Math.abs(y);
if ((x == 0) || (y == 0)) return 0;
while (y != 0) {
int r = x % y;
x = y;
y = r;
}
return x;
}
public String toString() {
if (den == 0)
return "NaF"; // Not A Fraction
else if (num == 0)
return "0";
else if (den == 1)
return ("" + num);
else
return num + "/" + den;
}
}
// SortableMutableInteger.java
// Similar to the Integer class, only the value is settable.
// Check out the test method for more details.
import java.util.*;
class SortableMutableInteger implements Comparable {
public static void main(String[] args) {
testSortableMutableIntegerClass();
}
public static void testSortableMutableIntegerClass() {
SortableMutableInteger[] a1 = { smi(3), smi(5), smi(1), smi(4), smi(2) };
System.out.println("Demonstrate that sorting works:");
System.out.println(" unsorted: " + Arrays.toString(a1));
Arrays.sort(a1);
System.out.println(" sorted: " + Arrays.toString(a1));
System.out.println("Testing SortableMutableInteger class... ");
// verify a1 is now sorted
SortableMutableInteger[] a2 = { smi(1), smi(2), smi(3), smi(4), smi(5) };
assert(Arrays.equals(a1, a2));
// verify we can modify an element in a1 (it is mutable)
assert(a1[0].getValue() == 1);
a1[0].setValue(6);
assert(a1[0].getValue() == 6);
Arrays.sort(a1);
SortableMutableInteger[] a3 = { smi(2), smi(3), smi(4), smi(5), smi(6) };
assert(Arrays.equals(a1, a3));
System.out.println("Passed all tests!");
}
// just an abbreviation for "new SortableMutableInteger(i)"
public static SortableMutableInteger smi(int i) {
return new SortableMutableInteger(i);
}
// Instance variable
private int intValue;
// constructor
public SortableMutableInteger(int intValue) {
this.intValue = intValue;
}
// accessor
public int getValue() {
return intValue;
}
// mutator
public void setValue(int intValue) {
this.intValue = intValue;
}
// toString
public String toString() {
return "SMI(" + intValue + ")";
}
// compareTo method (for Comparable interface)
public int compareTo(Object object) {
SortableMutableInteger that = (SortableMutableInteger) object;
return this.intValue - that.intValue;
}
// equals
public boolean equals(Object object) {
SortableMutableInteger that = (SortableMutableInteger) object;
return this.intValue == that.intValue;
}
// hashCode
// Simple "good-enough" general-purpose hashCode implementation
public int hashCode() {
int code = 1;
Object[] state = { this.intValue };
for (int i=0; i<state.length; i++)
code = 31*code + ((state[i] == null) ? 0 : state[i].hashCode());
return code;
}
}
// SortableName.java
// A "name" is a "first name" and "last name", and these
// are sortable by last-name-first.
// Check out the test method for more details.
import java.util.*;
class SortableName implements Comparable {
public static void main(String[] args) {
testSortableName();
}
public static void testSortableName() {
SortableName[] a1 = { sn("Grace Hopper"),sn("Charles Babbage"), sn("Grass Hopper"),
sn("Ada Lovelace"), sn("Eco Turing"), sn("Alan Turing") };
System.out.println("Demonstrate that sorting works:");
System.out.println(" unsorted: " + Arrays.toString(a1));
Arrays.sort(a1);
System.out.println(" sorted: " + Arrays.toString(a1));
System.out.println("Testing SortableName class... ");
// verify a1 is now sorted
SortableName[] a2 = { sn("Charles Babbage"), sn("Grace Hopper"), sn("Grass Hopper"),
sn("Ada Lovelace"), sn("Alan Turing"), sn("Eco Turing") };
assert(Arrays.equals(a1, a2));
// verify we can modify an element in a1 (it is mutable)
assert(a1[0].getFirstName().equals("Charles"));
assert(a1[0].getLastName().equals("Babbage"));
a1[0].setFirstName("Blaise");
a1[0].setLastName("Pascal");
assert(a1[0].getFirstName().equals("Blaise"));
assert(a1[0].getLastName().equals("Pascal"));
Arrays.sort(a1);
SortableName[] a3 = { sn("Grace Hopper"), sn("Grass Hopper"), sn("Ada Lovelace"),
sn("Blaise Pascal"), sn("Alan Turing"), sn("Eco Turing") };
assert(Arrays.equals(a1, a3));
System.out.println("Passed all tests!");
}
// just an abbreviation for "new SortableName(fullName)"
public static SortableName sn(String fullName) {
return new SortableName(fullName);
}
// Instance variables
private String firstName, lastName;
// constructor
public SortableName(String fullName) {
// simplified for demo purposes (does not handle cases like
// "Madonna" or "Robert Louis Stevenson").
int i = fullName.indexOf(' ');
this.firstName = fullName.substring(0, i);
this.lastName = fullName.substring(i+1);
}
// accessors
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
// mutators
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
// toString
public String toString() {
return "SN(" + firstName + " " + lastName + ")";
}
// compareTo method (for Comparable interface)
public int compareTo(Object object) {
SortableName that = (SortableName) object;
// compare last names first
int result = this.lastName.compareTo(that.lastName);
if (result == 0)
result = this.firstName.compareTo(that.firstName);
return result;
}
// equals
public boolean equals(Object object) {
SortableName that = (SortableName) object;
return (this.compareTo(that) == 0);
}
// hashCode
// Simple "good-enough" general-purpose hashCode implementation
public int hashCode() {
int code = 1;
Object[] state = { this.firstName, this.lastName };
for (int i=0; i<state.length; i++)
code = 31*code + ((state[i] == null) ? 0 : state[i].hashCode());
return code;
}
}
carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem