博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java类的Hash函数和集合类
阅读量:6477 次
发布时间:2019-06-23

本文共 2276 字,大约阅读时间需要 7 分钟。

equals和hashCode是自定义类中继承自Object类的子类需要重写的两个方法。

equals方法的作用在与检测一个对象是否等于另一个对象,默认的Object类方法判断两个对象的引用是否相同。Java语言规范要求equals方法具有以下特性:

  • 自反性:对于任何非空引用x,x.equals(x)返回true;

  • 对称性:对于任何引用x和y,如果y.equals(x)返回true,x.equals(y)也应该返回true;

  • 传递性:对于任何引用x,y,和z,如果x.equals(y)返回true,y.equals(z)返回true,x.equals(z)也应该返回true。

  • 一致性:如果x和y引用对象没有发生变化,x.equals(y)应该返回同样结果。

  • 任意非空引用x,x.equals(null)返回false。

由于子类拥有父类所不具有的独特的域,所以继承关系中,子类equals的实现需要仔细考虑如下问题:

  • 子类的相等性概念与父类的不同。如果子类的相等测试需要用到子类独有的域则对称性需求中使用getClass检测实现,例如Manager类是Employee类的子类,如果对象相等要求“分红”域相同,由于Employee中没有这个域,应该使用getClass检测相等性。

  • 子类的相等性概念是由父类决定的。如果子类的相等性概念与父类一致,则使用instanceOf进行对称性测试。同样是Manager类和Employee类,如果员工ID相同则是同一个对象,那么应该使用instanceOf进行检测。

完美的equals方法建议

  • 显示参数命名为otherObject,稍后将其转换成名为other的变量;

  • 检测this和otherObject是否引用同一个对象:

    if(this == otherObject) return true;
  • 检测是否属于同一个类:

如果子类的equals方法不同:

if(getClass() != otherObject.getClass()) return false;

如果与父类的equals方法一致:

if(!(otherObject instanceOf ClassName) return false;
  • 将otherObject转化为相应类型变量other;

  • 检测this和other的各个域是否相同,基本类型用==,对象域用equals方法,将所有域的比较用&&连接起来。

子类重新定义equals需要调用super.equals()方法。

另外需要注意的是,所覆盖的equals方法是Object类的方法,形如:equals(Object otherObject),注意参数。

Hash code是对象导出的整形值,默认的Object类的方法是对象的存储地址。(相同内容的String的hash code相同)。

如果重新定义了equals方法就必须要重新定义hashCode方法,使得对象能够放入散列表中。equals和hashCode方法的返回结果必须一致。

在Java中,散列表由链表数组实现,每个列表被称为桶。如果遇到散列冲突,需要用新对象与散列中的对象进行比较,查看对象是否已经存在。Java提供的HashSet类,实现了基于散列表的集合,contains方法只在某个桶中查找元素,而不必查看所有的元素。

问题:对于Java中的某个集合对象,如何判断一个值是否在这个集合中?判断时集合所采用的是equals方法还是contains方法?

针对这个问题,对大部分的Java集合中contains方法做了整理:

  • List集合:利用equals方法判断包含。

  • HashSet集合:利用hashCode和equals两个方法判断。通过hashCode定位到散列桶中,然后再利用equals方法判断是否存在。

  • TreeSet集合:被比较对象的类实现Comaprable接口或者在构造时传入Comparator接口的实现类。

  • HashMap集合:与HashSet相同。

  • TreeMap集合:与TreeSet相同。

附: Map中getEntry方法的实现:

final Entry
getEntry(Object key) { //得到key的hash code int hash = (key == null) ? 0 : hash(key.hashCode()); //遍历table里key的桶里的元素 for (Entry
e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; //判断如果hash值相等并且是同一个对象或者对象相等测试为真 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } return null;}

参考文章:

[1]Java核心技术,卷I

[2].

转载于:https://www.cnblogs.com/mrlocker/archive/2013/02/04/java_equality_hash_function_and_collections.html

你可能感兴趣的文章
Robot Framework自动化测试(三)---Selenium API
查看>>
解密短信木马为何屡杀不尽--android手机短信木马的攻与防
查看>>
设计模式六大原则(4):接口隔离原则
查看>>
MJRefresh用法
查看>>
LoadRunner参数化详解
查看>>
Java 理论和实践: 了解泛型 识别和避免学习使用泛型过程中的陷阱
查看>>
[翻译] DZNSegmentedControl
查看>>
[转] iOS 动画库 Pop 和 Canvas 各自的优势和劣势是什么?
查看>>
5招教你把握Java性能监控(转自51testing)
查看>>
10-穿墙代理的设置 | 01.数据抓取 | Python
查看>>
【SSH项目实战】国税协同平台-16.登录过滤器
查看>>
使用tbdba-restore-mysqldump.pl切割mysqldump文件
查看>>
【SpringMVC整合MyBatis】商品修改功能分析
查看>>
MySQL源码:JOIN顺序选择的复杂度
查看>>
【思货】kotlin协程优雅的与Retrofit缠绵-正文
查看>>
ES6入门之对象的新增方法
查看>>
Windows下配置SonarQube Scanner检测分析代码
查看>>
Node框架Express源码
查看>>
深入理解redux原理,从零开始实现一个简单的redux(包括react-redux, redux-thunk)
查看>>
您的简历该上锁了!
查看>>