【软件构造】设计安全高效的数据结构(3)(第8讲)

第八讲 数据结构实例的等价性

8.1 等价关系的性质

自反、对称、传递

8.2 不可变数据结构的等价

对象等价性:AF映射到相同的结果即等价。
在外部,对两个对象调用相同的操作,结果都一样。

  • 引用等价性:使用==来判断是不是同一个引用。
  • 对象等价性:使用equals来判断。

8.3 可变数据结构的等价

  • 观察等价性:在不改变状态的情况下,两个mutable对象是否看起来一致。(内容是否一致)
  • 行为等价性:调用对象的任何方法都展示出一致的结果。(一般方法,引用等价,直接继承Object)

当可变数据类型被放到Hash集合类中时,Hash类的equals不确定是不是真的。
有可能两个相等集合类进行比较是真的,变更一个之后,还是真的。

所以对可变类型来说,无需重写equals和hashCode,直接继承Object的两个方法即可。
如果一定要判断两个可变对象看起来是否一致,最好定义一个新的方法。

常见的可变数据类型的等价性

Date: 观察等价性,判断getTime的值是否相等。
集合类:观察等价性,比较每一个元素是否equals另一个集合类中的对应元素。
StringBuilder:行为等价性,继承自Object。

8.4 重写equals方法

在Object中,equals实现的是引用等价性,为了满足期望的结果一般需要重写。
值得注意的是,其第一个参数类型应该是Object,如果是其他的就是重载了。

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		VoteItem<?> other = (VoteItem<?>) obj;
		return Objects.equals(candidate, other.candidate) && Objects.equals(value, other.value);
	}
  • 还可以使用instanceof

8.5 重写hashCode方法

等价的对象,其hashCode()的结果必须一致。
因此一个类的equals和hashCode必须同时被重写。

@Override 
public int hashCode() {
	int result = 17; // Nonzero is good
	result = 31 * result + areaCode; // Constant must be odd
	result = 31 * result + prefix; // " " " "
	result = 31 * result + lineNumber; // " " " "
	return result;
}

@Override 
public int hashCode() {
	short[] hashArray = {areaCode, prefix, lineNumber};
	return Arrays.hashCode(hashArray);
}

@Override
public int hashCode() {
	return Objects.hash(candidate, value);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值