Java基础之集合框架——使用HashMap地图(TryPhoneBook1)

控制台程序。

首先改进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 }