item11: 重写equals后要重写hashCode
- 因为按照规定,equal的两个对象,它们的hashCode要一致,不equal的无要求。Object的equals是满足这个规定的
- 而重写的equals后,按照该类的equals方法相等的两个对象,如果按照Object的equals来说,应当是不相等的(相等就不用重写equals)。而Object的equals是满足规矩的,也就是说它们默认的hashcode不一定相等。也就是重写的equals不一定能满足规矩(因为按照规定,相等的对象,hashcode必须相等)
- 规定的作用是,比如在hashMap中,put(a)时是按照a.hashCode放到对应的桶内。HM.contains(b)判断对象b是否在HashMap中时,先通过hashCode定位到桶,但此时若是a.equals(b)但a和b有不同的hashCode,则此时的查找会到另一个桶中去查找,不能找到与b相等的a。即使由于偶然因素(哈希冲突),b能定位到a所在的桶,但由于HashMap在必须对象是否相等时,会先比较对象的hashCode,相等才进行后续比较,不相等则比较桶内其他元素。因此,也无法找到与b相等的a。
item12: 尽量重写toString方法。
- toString在很多地方会自动调用,如println等方法,没有重写,调用的是object的toString,其返回的是16进制的hashcode,本身意义不大。
- toString应包含所有 有用的,具有启发性的 属性,而且这些属性,应当是可以直接访问的。不然其他人想获取属性值只能解析toString返回的字符串。
- 静态工具类不需要重写toString(Item4:Enforce noninstantiability with a private constructor),抽象类都应该重写。其他情况,除非父类已重写,否则应该重写。
- 提供副本的方法最好直接使用 构造函数 (参数为需要产生副本的对象) 或 静态工厂(静态方法)。若是对象包含数组,可以考虑使用clone()