控制台程序。
首先改进Peron类,使Person可以在地图中用作键,进而存储电话簿中的项。必须添加equals()方法并重写默认的hashCode()方法。
1 import java.io.*; 2 3 public class Person implements Comparable<Person>, Serializable { 4 // Constructor 5 public Person(String firstName, String surname) { 6 this.firstName = firstName; 7 this.surname = surname; 8 } 9 10 @Override 11 public String toString() { 12 return firstName + " " + surname; 13 } 14 15 // Compare Person objects 16 public int compareTo(Person person) { 17 int result = surname.compareTo(person.surname); 18 return result == 0 ? firstName.compareTo(person.firstName) : result; 19 } 20 21 @Override 22 public boolean equals(Object person) { 23 return compareTo((Person)person) == 0; 24 } 25 26 @Override 27 public int hashCode() { 28 return 7*firstName.hashCode()+13*surname.hashCode(); 29 } 30 31 // Read a person from the keyboard 32 public static Person readPerson() { 33 String firstName = null; 34 String surname = null; 35 try { 36 System.out.print("Enter first name: "); 37 firstName = keyboard.readLine().trim(); 38 System.out.print("Enter surname: "); 39 surname = keyboard.readLine().trim(); 40 } catch(IOException e) { 41 System.err.println("Error reading a name."); 42 e.printStackTrace(System.err); 43 System.exit(1); 44 } 45 return new Person(firstName,surname); 46 } 47 48 private String firstName; // First name of person 49 private String surname; // Second name of person 50 private static final long serialVersionUID = 1001L; 51 private static BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in)); 52 }
对于可在散列表中用作键的自定义类对象来说,必须重写Object类的equals()方法。该方法有HashMap<>类中的方法用于确定两个键何时相等。
还可以重写默认的hashCode()方法,将对象的散列值返回为int类型。这个hashCode()方法用于生成一个值,从而确定键/值位于什么地方。
1 import java.io.*; 2 3 class PhoneNumber implements Serializable { 4 public PhoneNumber(String areacode, String number) { 5 this.areacode = areacode; 6 this.number = number; 7 } 8 9 @Override 10 public String toString() { 11 return areacode + " " + number; 12 } 13 14 // Read a phone number from the keyboard 15 public static PhoneNumber readNumber() { 16 String area = null; // Stores the area code 17 String localcode = null; // Stores the local code 18 try { 19 System.out.print("Enter area code: "); 20 area = keyboard.readLine().trim(); 21 System.out.print("Enter local code: "); 22 localcode = keyboard.readLine().trim(); 23 System.out.print("Enter the number: "); 24 localcode += " " + keyboard.readLine().trim(); 25 } catch(IOException e) { 26 System.err.println("Error reading a phone number."); 27 e.printStackTrace(); 28 System.exit(1); 29 } 30 return new PhoneNumber(area,localcode); 31 } 32 33 private String areacode; 34 private String number; 35 private static final long serialVersionUID = 1001L; 36 private static BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in)); 37 }
1 import java.io.Serializable; 2 3 class BookEntry implements Serializable { 4 public BookEntry(Person person, PhoneNumber number) { 5 this.person = person; 6 this.number = number; 7 } 8 9 public Person getPerson() { 10 return person; 11 } 12 13 public PhoneNumber getNumber() { 14 return number; 15 } 16 17 @Override 18 public String toString() { 19 return person.toString() + ' ' + number.toString(); 20 } 21 22 // Read an entry from the keyboard 23 public static BookEntry readEntry() { 24 return new BookEntry(Person.readPerson(), PhoneNumber.readNumber()); 25 } 26 27 private Person person; 28 private PhoneNumber number; 29 private static final long serialVersionUID = 1001L; 30 }
1 import java.io.Serializable; 2 import java.util.HashMap; 3 4 class PhoneBook implements Serializable { 5 public void addEntry(BookEntry entry) { 6 phonebook.put(entry.getPerson(), entry); 7 } 8 9 public BookEntry getEntry(Person key) { 10 return phonebook.get(key); 11 } 12 13 public PhoneNumber getNumber(Person key) { 14 BookEntry entry = getEntry(key); 15 if(entry != null) { 16 return entry.getNumber(); 17 } else { 18 return null; 19 } 20 } 21 22 private HashMap<Person,BookEntry> phonebook = new HashMap<>(); 23 private static final long serialVersionUID = 1001L; 24 }
1 import java.io.StreamTokenizer; 2 import java.io.BufferedReader; 3 import java.io.InputStreamReader; 4 import java.io.IOException; 5 6 public class FormattedInput { 7 8 public int readInt() throws InvalidUserInputException { 9 if (readToken() != StreamTokenizer.TT_NUMBER) { 10 throw new InvalidUserInputException("readInt() failed." + "Input data not numeric"); 11 } 12 13 if (tokenizer.nval > (double) Integer.MAX_VALUE || tokenizer.nval < (double) Integer.MIN_VALUE) { 14 throw new InvalidUserInputException("readInt() failed." + "Input outside range of type int"); 15 } 16 17 if (tokenizer.nval != (double) (int) tokenizer.nval) { 18 throw new InvalidUserInputException("readInt() failed." + "Input not an integer"); 19 } 20 return (int) tokenizer.nval; 21 } 22 23 public double readDouble() throws InvalidUserInputException { 24 if (readToken() != StreamTokenizer.TT_NUMBER) { 25 throw new InvalidUserInputException("readDouble() failed." + "Input data not numeric"); 26 } 27 return tokenizer.nval; 28 } 29 30 public String readString() throws InvalidUserInputException { 31 if (readToken() == StreamTokenizer.TT_WORD || ttype == '"' || ttype == '"') { 32 return tokenizer.sval; 33 } else { 34 throw new InvalidUserInputException("readString() failed." + "Input data is not a string"); 35 } 36 } 37 // Plus methods to read various other data types... 38 39 // Helper method to read the next token 40 private int readToken() { 41 try { 42 ttype = tokenizer.nextToken(); 43 return ttype; 44 45 } catch (IOException e) { // Error reading in nextToken() 46 e.printStackTrace(); 47 System.exit(1); // End the program 48 } 49 return 0; 50 } 51 52 // Object to tokenize input from the standard input stream 53 private StreamTokenizer tokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); 54 private int ttype; // Stores the token type code 55 }
1 public class InvalidUserInputException extends Exception { 2 public InvalidUserInputException() { } 3 4 public InvalidUserInputException(String message) { 5 super(message); 6 } 7 8 private static final long serialVersionUID = 9876L; 9 10 }
1 public class TryPhoneBook { 2 public static void main(String[] args) { 3 PhoneBook book = new PhoneBook(); // The phone book 4 FormattedInput in = new FormattedInput(); // Keyboard input 5 Person someone; 6 while(true) { 7 System.out.println("Enter 1 to enter a new phone book entry "+ 8 "Enter 2 to find the number for a name "+ 9 "Enter 9 to quit."); 10 int what = 0; // Stores input selection 11 try { 12 what = in.readInt(); 13 14 } catch(InvalidUserInputException e) { 15 System.out.println(e.getMessage()+" Try again."); 16 continue; 17 } 18 19 switch(what) { 20 case 1: 21 book.addEntry(BookEntry.readEntry()); 22 break; 23 case 2: 24 someone = Person.readPerson(); 25 BookEntry entry = book.getEntry(someone); 26 if(entry == null) { 27 System.out.println("The number for " + someone + " was not found."); 28 } else { 29 System.out.println("The number for " + someone + " is " + entry.getNumber()); 30 } 31 break; 32 case 9: 33 System.out.println("Ending program."); 34 return; 35 default: 36 System.out.println("Invalid selection, try again."); 37 break; 38 } 39 } 40 } 41 }