001package algs34; 002import stdlib.*; 003import java.util.HashSet; 004/* *********************************************************************** 005 * Compilation: javac PhoneNumber.java 006 * Execution: java PhoneNumber 007 * Dependencies: 008 * 009 * Mutable data type for US phone numbers, with overridden versions 010 * equals and hashcode. This can cause data to get lost in java.util.HashSet. 011 * 012 * DO NOT USE THIS CLASS 013 *************************************************************************/ 014 015public final class XPhoneNumberMutable { 016 private int area; // area code (3 digits) 017 private int exch; // exchange (3 digits) 018 private int ext; // extension (4 digits) 019 020 public XPhoneNumberMutable(int area, int exch, int ext) { 021 this.area = area; 022 this.exch = exch; 023 this.ext = ext; 024 } 025 026 public void set(int area, int exch, int ext) { 027 this.area = area; 028 this.exch = exch; 029 this.ext = ext; 030 } 031 032 // how you're supposed to implement equals 033 public boolean equals(Object y) { 034 if (y == this) return true; 035 if (y == null) return false; 036 if (y.getClass() != this.getClass()) return false; 037 XPhoneNumberMutable that = (XPhoneNumberMutable) y; 038 return (this.area == that.area) && (this.exch == that.exch) && (this.ext == that.ext); 039 } 040 041 // 0 for padding with leading 0s 042 public String toString() { 043 return String.format("(%03d) %03d-%04d", area, exch, ext); 044 } 045 046 // satisfies the hashCode contract 047 public int hashCode() { 048 int h = 17; 049 h = ext + 31 * h; 050 h = exch + 31 * h; 051 h = area + 31 * h; 052 return h; 053 } 054 055 056 public static void main(String[] args) { 057 XPhoneNumberMutable a = new XPhoneNumberMutable(609, 258, 4455); 058 XPhoneNumberMutable b = new XPhoneNumberMutable(609, 876, 5309); 059 XPhoneNumberMutable c = new XPhoneNumberMutable(609, 003, 5309); 060 XPhoneNumberMutable d = new XPhoneNumberMutable(215, 876, 5309); 061 XPhoneNumberMutable e = new XPhoneNumberMutable(609, 876, 5309); 062 StdOut.format("a = %s [hashcode=%d]\n", a, a.hashCode ()); 063 StdOut.format("b = %s [hashcode=%d]\n", b, b.hashCode ()); 064 StdOut.format("c = %s [hashcode=%d]\n", c, c.hashCode ()); 065 StdOut.format("d = %s [hashcode=%d]\n", d, d.hashCode ()); 066 StdOut.format("e = %s [hashcode=%d]\n", e, e.hashCode ()); 067 068 HashSet<XPhoneNumberMutable> set = new HashSet<>(); 069 set.add(a); 070 set.add(b); 071 set.add(c); 072 StdOut.println("\nAdded a, b, and c: " + set); 073 StdOut.println("contains a: " + set.contains(a)); 074 StdOut.println("contains b: " + set.contains(b)); 075 StdOut.println("contains c: " + set.contains(c)); 076 StdOut.println("contains d: " + set.contains(d)); 077 StdOut.println("contains e: " + set.contains(e)); 078 StdOut.println("b == e: " + (b == e)); 079 StdOut.println("b.equals(e): " + (b.equals(e))); 080 081 c.set(609, 876, 5309); 082 b.set(609, 003, 5309); 083 StdOut.format("\na = %s [hashcode=%d]\n", a, a.hashCode ()); 084 StdOut.format("b = %s [hashcode=%d]\n", b, b.hashCode ()); 085 StdOut.format("c = %s [hashcode=%d]\n", c, c.hashCode ()); 086 StdOut.format("d = %s [hashcode=%d]\n", d, d.hashCode ()); 087 StdOut.format("e = %s [hashcode=%d]\n", e, e.hashCode ()); 088 StdOut.println("\nSwapped values of b and c: " + set); 089 StdOut.println("contains a: " + set.contains(a)); 090 StdOut.println("***contains b: " + set.contains(b)); 091 StdOut.println("***contains c: " + set.contains(c)); 092 StdOut.println("contains d: " + set.contains(d)); 093 StdOut.println("***contains e: " + set.contains(e)); 094 StdOut.println("c == e: " + (c == e)); 095 StdOut.println("c.equals(e): " + (c.equals(e))); 096 097 } 098 099 100 101}