优雅编程之这样使用对象通用方法,你就“正常”了(三十四)
来源:互联网 发布:sql nvl函数用法 编辑:程序博客网 时间:2024/05/22 10:21
开心一笑
【一对夫妇避孕失败后生了一个小男孩,孩子一生出来就紧握拳头,一直笑个不停.护士把他的拳头一掰开.发现里面有一把避孕药,接着小男孩开口说话了:“你们两个想弄死我,没那么容易,哈哈哈】
提出问题**
项目开发中,对对象都通用的方法要注意那些???
解决问题
覆盖equals时请遵守通用约定
先温习下枯燥的理论知识,很无聊,但很重要。
- 自反性:对于任何非null的引用值x,x.equals(x)必须返回true.
- 对称性:对于非空的引用值x,y,当且仅当x.equals(y)返回true时,y.equals(x)必须返回true.
- 传递性:对于任何非null的引用值x,y,z,如果x.equals(y)=true,y.equals(z)=true,那么x.equals(z)也必须返回true。
- 一致性:对于任何非null的引用值x,y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或一致地返回false.
- 对于非null的引用值x,x.equals(null)必须返回false.
高质量equals方法的诀窍
- 使用==操作符检查参数是否为这个对象的引用。
- 使用instanceof操作符检查参数是否为正确的类型。
- 把参数转换成正确的类型。
- 当编写完成了equals方法之后,应该问自己三个问题,它是否是对称的、传递的、一致的。
我用开发工具自动帮我生成equals方法:
@Overridepublic boolean equals(Object o) { //使用==操作符检查参数是否为这个对象的引用 if (this == o) return true; //使用instanceof操作符检查参数是否为正确的类型 if (!(o instanceof AyTest)) return false; //把参数转换成正确的类型 AyTest ayTest = (AyTest) o; if (flowerNum != ayTest.flowerNum) return false; return true;}
覆盖equals时总要覆盖hashCode
覆盖equals方法,必须覆盖hashCode方法。如果不这样做,就会违反Object.hashCode的通用约定,从而也导致该类无法结合所有基于散列的结合一块正常运转,这样的结合包括HashMap、HashSet和Hashtable
//这里引用课本的例子,非原创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); } } @Override public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof PhoneNumber)) { return false; } PhoneNumber pNumber = (PhoneNumber)o; return (pNumber.lineNumber == lineNumber) && (pNumber.prefix == prefix) && (pNumber.areaCode == areaCode); } }
测试例子:
public static void hashCodePhoneNumber() { Map<PhoneNumber, String> map = new HashMap<PhoneNumber, String>(); PhoneNumber phoneNumber = new PhoneNumber(707, 867, 9876); map.put(phoneNumber, "Jenny"); //这里是重点 重点 重点 一个是new 出来的 一个是 原来的phoneNumber System.out.println(map.get(new PhoneNumber(707, 867, 9876))); System.out.println(map.get(phoneNumber)); }
执行结果:
null Jenny
解释一下:
不去覆盖hashCode,使用map.put时,我们是把这些PhoneNumber对象放在各个不同的盒子里,而我们去map.get()的时候,只是去某一个盒子里去找,而如果我们覆盖了hashCode方法,这时,如果通过hashCode计算出来的值是相等的,就会放在同一个盒子里。这样,只要我们对象中保存的值是完全一致的,就会找到这个key所对应的value。
始终要覆盖toString
如果我们不覆盖类的toString()方法,后果可能是当我们需要去打印这个类的对象时,会有一些并非是我们想要的那种结果。现在开发工具很方便,可以使用开发工具自动帮助我们生成。
谨慎的覆盖clone
拷贝的含义是:
- x.clone() != x
- x.clone().getClass() == x.getClass()
- x.clone().equals(x)
覆盖clone方法要非常小心,如果类里面含有复杂数据类型,要进行深度复制,如果类里面有final属性,则无法进行clone,因为final属性在clone时无法再进行赋值。
最好呢就是别去覆盖这个方法,需要复制的话可以使用拷贝构造器和静态拷贝工厂
考虑实现Comparable接口
comparaTo方法不是Object中的方法,而是Comparable接口中唯一的方法。该方法不仅可进行等同性比较,还可以进行顺序比较。
接口的通用约定是按照equals方法来定义的,但有序集合使用了compareTo方法的等同性测试。
如果是是一个值类,而且具有明显的内在排序关系,就因该坚决实现该接口。
如果你正在编写一个值类,它具有非常明显的内在排序关系,比如按字母顺序、按数值顺序或者按照年代顺序,那就应该坚决考虑实现这个接口。
参考文章
【1】Effective Java:对于所有对象都通用的方法
【2】Java中equals和==的区别
【3】Effective Java——对所有对象通用的方法
【4】Effective Java 读书笔记之二 对于所有对象都通用的方法
【5】考虑实现Comparable接口
读书感悟
来自韩寒《我所理解的生活》
- 我所理解的生活就是做着自己喜欢的事情,养活自己,养活家人。生活不是攀爬高山,也不是深潜海沟,它只是在一张标配的床上睡出你的身形。我所理解的生活就是和自己喜欢的一切在一起。
- 缘分不是走在街上非要撞见,缘分就是睡前醒后彼此想念。
- 打死也不能放弃,穷死也不能叹气,要让笑话你的人成为笑话。
- 可以后悔,但不留遗憾,有很多事情做了以后发现自己傻了或者失败了,但还是要去做。
- 世间万千种宠爱,无数种人心,得之我幸,不得我也没什么不幸。
- 我相信真诚相待,也相信倒霉认栽。
- 每个人的道路都不同,我走在我的野路上,她走在她的大路上,都值得祝福。只要不走歪路邪路,每条道路都有成功的方式。
其他
如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!
- 优雅编程之这样使用对象通用方法,你就“正常”了(三十四)
- 优雅编程之这样使用对象,你就“正常”了(三十二)
- 优雅编程之这样使用CollectionUtils,你就“正常”了
- 优雅编程之这样设计通用程序,你就“正常”了(二十七)
- 优雅编程之这样重构对象,你就“正常”了(二十一)
- 优雅编程之这样编写方法,你就“正常”了(二十八)
- 优雅编程之这样使用工具,你就“正常”了(十三)
- 优雅编程之这样使用枚举和注解,你就“正常”了(二十九)
- 优雅编程之这样使用类和接口,你就“正常”了(三十)
- 优雅编程之这样使用泛型,你就“正常”了(三十三)
- 优雅编程之这样使用CollectionUtils,你就“正常”了(三十五)
- 优雅编程之这样使用Map,你就“正常”了(三十六)
- 优雅编程之这样写函数,你就“正常”了!
- 优雅编程之这样注释代码,你就“正常”了!
- 优雅编程之这样取名字,你就"正常"了!
- 优雅编程之这样格式代码,你就"正常了"!
- 优雅编程之这样创建类,你就“正常”了!
- 优雅编程之这样处理异常,你就“正常”了!
- 实习汇总:爱奇艺、安永、网易、滴滴、百度、优酷、国家统计局、搜狐、爱立信
- data science cs109 homework1
- Easy 13题 Roman to Integer
- POJ 3625(朴素prim)
- 程序员要注意身体健康
- 优雅编程之这样使用对象通用方法,你就“正常”了(三十四)
- 极客学院30天免费vip
- go语言特性113
- GT4编程实例
- caffe配置文件 网络lenet-train-test.prototxt注释及说明
- Linux设备模型 - linux-4.0-rc1
- Android简易实战教程--第三十六话《电话录音》
- 你所不知道的 Console
- codeforces round 376 Div2 D~F