/******************************************************************************
* Compilation: javac Student.java
* Execution: java Student
* Dependencies: StdOut.java
*
* Illustrates implementation of a Comparator and equals() method.
*
* % By name
* ----------
* 2 Alice
* 1 Bob
* 2 Carol
* 1 Dave
* 2 Eve
* 3 Frank
* 1 Grant
* 3 Helia
* 3 Isaac
* 1 Jen
* 1 Kevin
* 2 Larry
*
* By section
* ----------
* 1 Bob
* 1 Dave
* 1 Grant
* 1 Jen
* 1 Kevin
* 2 Alice
* 2 Carol
* 2 Eve
* 2 Larry
* 3 Frank
* 3 Helia
* 3 Isaac
*
* By Kevin
* ----------
* 1 Kevin
* 2 Larry
* 2 Alice
* 1 Bob
* 2 Carol
* 1 Dave
* 2 Eve
* 3 Frank
* 1 Grant
* 3 Helia
* 3 Isaac
* 1 Jen
*
******************************************************************************/
import java.util.Arrays;
import java.util.Comparator;
/**
* The {@code Student} class is an immutable data type to encapsulate a
* student name and section number. It is used to illustrate various
* comparators.
*
* For additional documentation,
* see Section 1.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Student {
public static final Comparator NAME_ORDER = new NameOrder();
/**
* A comparator for comparing students in ascending order by section number.
*/
public static final Comparator SECTION_ORDER = new SectionOrder();
private final String name;
private final int section;
/**
* Initializes a new student from the given arguments.
*
* @param name the name of this student
* @param section the section number of this student
*/
public Student(String name, int section) {
this.name = name;
this.section = section;
}
/**
* Returns a comparator for comparing students in lexicographic order by name.
*
* @return a {@link Comparator} for comparing students in lexicographic order by name
*/
private static Comparator byNameOrder() {
return new NameOrder();
}
/**
* Returns a comparator for comparing students in numerical order by section.
*
* @return a {@link Comparator} for comparing students in numerical order by section
*/
private static Comparator bySectionOrder() {
return new SectionOrder();
}
// compare students by names, starting at this student's name
// and wrapping around alphabetically
private Comparator byRelativeNameOrder() {
return new RelativeNameOrder();
}
// comparator to sort by name
private static class NameOrder implements Comparator {
public int compare(Student a, Student b) {
return a.name.compareTo(b.name);
}
}
// comparator to sort by section
private static class SectionOrder implements Comparator {
public int compare(Student a, Student b) {
return a.section - b.section;
}
}
// comparator to sort by name with this name first
// illustrates the use of a non-static comparator
private class RelativeNameOrder implements Comparator {
public int compare(Student a, Student b) {
if (a.name.compareTo(b.name) == 0) return 0;
if (a.name.compareTo(name) == 0) return -1;
if (b.name.compareTo(name) == 0) return +1;
if ((a.name.compareTo(name) < 0) && (b.name.compareTo(name) > 0))
return +1;
if ((a.name.compareTo(name) > 0) && (b.name.compareTo(name) < 0))
return -1;
return a.name.compareTo(b.name);
}
}
/**
* Compares this student to the specified student.
*
* @param other the other student
* @return {@code true} if this student equals {@code other};
* {@code false} otherwise
*/
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
Student that = (Student) other;
return (this.section == that.section) && (this.name.equals(that.name));
}
@Override
public int hashCode() {
return 31*section + name.hashCode();
}
@Override
public String toString() {
return section + " " + name;
}
/**
* Unit tests the {@code Student} data type.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
// create an array of students
Student alice = new Student("Alice", 2);
Student bob = new Student("Bob", 1);
Student carol = new Student("Carol", 2);
Student dave = new Student("Dave", 1);
Student eve = new Student("Eve", 2);
Student frank = new Student("Frank", 3);
Student grant = new Student("Grant", 1);
Student helia = new Student("Helia", 3);
Student isaac = new Student("Isaac", 3);
Student jen = new Student("Jen", 1);
Student kevin = new Student("Kevin", 1);
Student larry = new Student("Larry", 2);
Student[] students = {
larry, kevin, jen, isaac, grant, helia,
frank, eve, dave, carol, bob, alice
};
// sort by name and print results
StdOut.println("By name");
StdOut.println("----------");
Arrays.sort(students, Student.byNameOrder());
for (int i = 0; i < students.length; i++)
StdOut.println(students[i]);
StdOut.println();
// now, sort by section and print results
StdOut.println("By section");
StdOut.println("----------");
Arrays.sort(students, Student.bySectionOrder());
for (int i = 0; i < students.length; i++)
StdOut.println(students[i]);
StdOut.println();
// now, sort by name relative to Kevin
StdOut.println("By Kevin");
StdOut.println("----------");
Arrays.sort(students, kevin.byRelativeNameOrder());
for (int i = 0; i < students.length; i++)
StdOut.println(students[i]);
StdOut.println();
Student ali = new Student("Alice", 3);
String fred = "Fred";
StdOut.println("alice == ali: " + (alice == ali));
StdOut.println("alice.equals(ali): " + (alice.equals(ali)));
StdOut.println("alice.equals(bob): " + (alice.equals(bob)));
StdOut.println("alice.equals(fred): " + (alice.equals(fred)));
}
}