该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

覆盖equals时请遵守通用约定

我们知道equals要实现的是逻辑上的相等。站在数学的角度来看,两个事物相等的条件,有如下几个:

1.自反性:对于任何非null的引用值x,x.equals(x)必须返回true.

2.对称性:对于非空的引用值x,y,当且仅当x.equals(y)返回true时,y.equals(x)必须返回true.

3.传递性:对于任何非null的引用值x,y,z,如果x.equals(y)=true,y.equals(z)=true,那么x.equals(z)也必须返回true。

4.一致性:对于任何非null的引用值x,y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或一致地返回false.

5.对于非null的引用值x,x.equals(null)必须返回false.

2

覆盖equals时总要覆盖hashCode

我们来看下面的例子:

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 numb er");

this.areaCode = (short)areaCode;

this.prefix = (short)prefix;

this.lineNumber = (short)lineNumber;

}

private static void rangeCheck(int arg, int ma x, String name) {

if (arg < 0 || arg > max) {

throw new IllegalArgumentException(na me + ": " + 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 == lineNumb er) && (pNumber.prefix == prefix) && (p Number.areaCode == areaCode);

}

}

测试代码:

public static void hashCodePhoneNumber() {

Map map = new H ashMap();

PhoneNumber phoneNumber = new Phon eNumber(707, 867, 9876);

map.put(phoneNumber, "Jenny");

System.out.println(map.get(new PhoneNu mber(707, 867, 9876)));

System.out.println(map.get(phoneNumbe r));

}

输出的结果:

null

Jenny

我们可以这样来理解上面的map.put()。如果我们不去覆盖hashCode,那么当我们使用map.put时,我们是把这些PhoneNumber对象放在各个不同的盒子里,而我们去map.get()的时候,只是去某一个盒子里去找(当然,如果map.get()和map.put()中的对象是同一个的话,当然可以找到)。

而如果我们覆盖了hashCode方法,这时,如果通过hashCode计算出来的值是相等的,就会放在同一个盒子里。这样,只要我们对象中保存的值是完全一致的,就会找到这个key所对应的value。不知道你发现没有,这个hashCode有点类似于分类,这样在数据量比较大的情况下就会大大提高效率。

我们可以通过以下两种方法来覆盖hashCode方法:

方法一

@Override

public int hashCode() {

return 42;

}

方法二

@Override

public int hashCode() {

int result = 17;

result = 31 * result + areaCode;

result = 31 * result + prefix;

result = 31 * result + lineNumber;

return result;

}

首先两种方法都可以。通过上面的分析,从效率的角度来考虑,当然是第二种方法更为恰当。所以在覆盖了equlas的同时,别忘了去覆盖hashCode.

3

始终覆盖toString方法

如果我们不去覆盖类的toString()方法,后果就是当我们需要去打印这个类的对象时,会有一些并非是我们想要的那种。类似这样的:com.java.effective.samples.PhoneNumber@12a7e3

有时我们不希望打印出这样的对象,那我们就要去覆盖它们的toString方法了。在这个方法里,我们可以按照我们自己的意愿来给类添加toString方法。对于PhoneNumber,我们可以这样来写:

@Override

public String toString() {

String result = "";

result += (areaCode + "-");

result += (prefix + "-");

result += (lineNumber);

return result;

}

理博软件,高薪就业的摇篮

java 通用对象_java中对所有对象都通用的方法相关推荐

  1. java如果把字符串转成对象_Java中的重复对象:不仅仅是字符串

    当Java应用程序消耗大量内存时,它本身就会出现问题,并可能导致GC压力增加和GC暂停时间过长.在我之前的一篇文章中,我讨论了Java中常见的内存浪费源:重复字符串.两个 java.lang.Stri ...

  2. java 组合对象_Java 中组合模型之对象结构模式的详解

    Java 中组合模型之对象结构模式的详解 一.意图 将对象组合成树形结构以表示"部分-整体"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 二.适用性 ...

  3. java堆栈异常_Java中获得异常堆栈使用轨迹的方法是。

    Java中获得异常堆栈使用轨迹的方法是. 答:fillinStack() 中国大学MOOC: 互联网金融品牌建设能增加客户对企业的依赖度,促使客户重复使用某个企业产品或服务,从而产生一定的客户黏性 答 ...

  4. java 当月最后一天_java中取得当月最后一天的四种方法

    java中取得当月最后一天的四种方法 第一种,使用Calendar的roll方法,在限制某个日期字段不改变的形式下,改变其他日期字段的值. 第二种,使用Calendar的getActualMaximu ...

  5. java取子串_Java中获取子字符串的几种方法示例

    首先假如有这样一串字符串: String s = "共 100 页, 1 2 3 4..."; 假如我想把"100"给取出来,该如何做? 方法一: 采用spli ...

  6. java中的map对象_java中遍历Map对象的四种方式

    import java.util.HashMap; import java.util.Map; /** * 遍历Map对象 * @author xiaosongsong: * @CreateTime ...

  7. java 数组排序论文_Java中运用数组的四种排序方法

    标签: <1>利用Arrays带有的排序方法快速排序 import java.util.Arrays; 2 public class Test2{ public static void m ...

  8. java properties用法_java中Properties文件加载和使用方法

    一.Properties简介 Properties 类继承自HashTable,提供的方法很像Map的实现类HashMap.它在 Java 编程的早期就有了,并且几乎没有什么变化.J2SE 的 Tig ...

  9. java设置行间距_Java中调整字距与行距的方法 其一(以DrawString为例)

    今天要谈的是如何在Java中调整字距与行距,当然,这里谈的主要是针对swing与awt里的字距与行距. 调整字距与行距看起来似乎是个很简单的问题,大概可以直接调用某个内置的方法来操作,紫雾我最开始也是 ...

最新文章

  1. linux 国内 NTP时间服务器地址
  2. Oralce数据库之存储过程、存储函数、触发器和数据字典
  3. CentOS下Hive2.0.0集群模式安装详解
  4. html页面滚动导致阴影出现,三种处理滚动穿透问题方案的对比
  5. 家中路由添加静态IP映射(一)
  6. 7wifi模块多少钱_APP开发要多少钱?创业者估算成本的四个方法
  7. paip.php and or 语句用法作用
  8. 2021年中国直播电商投融资情况及行业发展中存在的问题、发展趋势和对策分析[图]
  9. LESSON 10.3 Halving网格搜索
  10. 文档数据库-MongoDB
  11. 如何回答「你的优势和劣势是什么」?【面试核心问题6】
  12. 2017工业互联网峰会 | 天拓四方助力中国工业生产、制造业转型升级
  13. Oracle-存储过程语法
  14. python人口热力图_利用Python绘制中国大陆人口热力图
  15. 超级电容锂电池混合储能Simulink仿真
  16. Microsoft OLE DB Provider for ODBC Drivers (0x80004005) 操作必须使用一个可更新的查询”错误的解决办法
  17. 合并报表软件工具怎么用?
  18. 2个在线运行SQL的网站,强的离谱!
  19. 英特尔争分夺秒,以物联网技术破局智慧医疗
  20. 同样是远程办公,为什么有的企业运转效率还提高了?

热门文章

  1. 关于centos 7 中service iptables save 指令使用失败的结局方案
  2. “相当一部分”HPE公司OpenStack工作人员被转移至SUSE
  3. 上传一个 游戏server架构图
  4. 0918类对象重载,作业3
  5. C++:流类库与输入输出
  6. storm生产环境部署问题
  7. jQuery对象和DOM对象的区别和转换
  8. Magento调用静态块 static block
  9. C语言——冒泡排序法
  10. 平衡点 / 吊打XXX(洛谷-P1337)