I encountered a problem during my interview today. The code for the problem is as follows:
import java.util.HashMap;import java.util.Map;public final class PhoneNumber { private final short areaCode; private final short prefix; private final short lineNumber; public PhoneNumber(int areaCode,int prefix,int lineNumber){ rangeCheck(areaCode, 999, "area code"); rangeCheck(prefix, 999, "prefix"); rangeCheck(lineNumber, 9999, "line number"); this.areaCode=(short)areaCode; this.prefix=(short)prefix; this.lineNumber=(short)lineNumber; } private static void rangeCheck(int arg,int max,String name){ if(arg<0||arg>max){ throw new IllegalArgumentException(name+":"+arg); } }@Overridepublic boolean equals(Object o) { if(o==this) return true; if(!(o instanceof PhoneNumber)) return false; PhoneNumber pn=(PhoneNumber) o; return (pn.lineNumber==lineNumber)&&(pn.prefix==prefix)&&(pn.areaCode==areaCode);return false; } public static void main(String[] args){ Map<PhoneNumber, String> m=new HashMap<PhoneNumber, String>(); PhoneNumber pn=new PhoneNumber(707,067, 5309); m.put(new PhoneNumber(707,067, 5309), "jenny"); System.out.println(m.get(new PhoneNumber(707,067, 5309))); }}
The problem is to check the output result after the program is executed. I had a question but I was not sure. He didn't rewrite the hashcode method, I think that the equals method and the hashcode method are both recommended. So I think there is a trap in this question, but I don't know where there is a trap. I typed the program and found that the output result is null. I guess it must be related to hashcode. So I added an endpoint before the PUT Method of MAP and entered the source code of hashmap for single-step debugging, I found that the hashcode method is called when the key is accessed in the source code. By default, if the hashcode method is not overwritten, the default hashcode is called, that is, the object hash code, therefore, different objects have different hash codes, which are then stored Based on the hash codes. When the get method is called, the value is obtained based on the hash code. If the value exists, the eqals method is called, therefore, even if the equals method returns true, it is useless to rewrite the hashcode so that it returns the same hash code. I changed the code to the following format and then returned Jenny.
import java.util.HashMap;import java.util.Map;public final class PhoneNumber { private final short areaCode; private final short prefix; private final short lineNumber; public PhoneNumber(int areaCode,int prefix,int lineNumber){ rangeCheck(areaCode, 999, "area code"); rangeCheck(prefix, 999, "prefix"); rangeCheck(lineNumber, 9999, "line number"); this.areaCode=(short)areaCode; this.prefix=(short)prefix; this.lineNumber=(short)lineNumber; } private static void rangeCheck(int arg,int max,String name){ if(arg<0||arg>max){ throw new IllegalArgumentException(name+":"+arg); } }@Overridepublic boolean equals(Object o) { if(o==this) return true; if(!(o instanceof PhoneNumber)) return false; PhoneNumber pn=(PhoneNumber) o; return (pn.lineNumber==lineNumber)&&(pn.prefix==prefix)&&(pn.areaCode==areaCode);return false; }@Overridepublic int hashCode(){return 7*(new Integer(lineNumber).hashCode())+11*(new Integer(prefix)).hashCode()+13*(new Integer(areaCode).hashCode());} public static void main(String[] args){ Map<PhoneNumber, String> m=new HashMap<PhoneNumber, String>(); PhoneNumber pn=new PhoneNumber(707,067, 5309); m.put(new PhoneNumber(707,067, 5309), "jenny"); System.out.println(m.get(new PhoneNumber(707,067, 5309))); System.out.println(pn.getClass()); }}
Now let's take a look at the difference between the equals method and =. By default, = is used to compare whether the references of the two objects are equal. If equsls is not overwritten, It is compared by default according to =. = It is generally used to compare whether two basic types are equal. We also use the equals method when comparing strings, that is because the equals method and hashcode method have been overwritten in the string class, and the value size is compared.