文章目录
1.equals() 的作用?
equals() 作用 :用来判断两个对象是否相等。
equals()方法定义在java.lang.Object
中,意味着对于所有的类,都含有它们的equals()
方法,定义如下:
public boolean equals(Object obj) {
return (this == obj);
}
我们根据类是否重写了equals()方法,分为两种情况
1.1没有覆盖equals()方法
该情况则是使用默认equals()方法(如上所示),此时的equals()
方法与==
等价,当用它比较两个对象的时候,就是判断两个对象是否是同一个对象(地址是否相等)。
// 举当前例子说明
public class TestEquals {
public static void main(String[] args) {
Student s1 = new Student("小明", 10);
Student s2 = new Student("小明", 10);
System.out.println(s1.equals(s2));
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
// 运行结果:false
1.2覆盖equals()方法
该情况由程序员自己覆盖实现equals()
方法,用我们自定义的equals()
方法比较两个对象是否相等;通常是比较两个对象的内容是否相等(如String类)。
// 举当前例子说明
public class TestEquals {
public static void main(String[] args) {
Student s1 = new Student("小明", 10);
Student s2 = new Student("小明", 10);
System.out.println(s1.equals(s2));
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
// 判断是否同一个对象
if (this == obj)
return true;
if (obj == null)
return false;
// 判断类型是否相同
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
// 运行结果:
1.3覆盖equals()方法的要求
- 对称性:如果x.equals(y)返回是"true",那么y.equals(x)也应该返回是"true"。
- 反射性:x.equals(x)必须返回是"true"。
- 类推性:如果x.equals(y)返回是"true",而且y.equals(z)返回是"true",那么z.equals(x)也应该返回是"true"。
- 一致性:如果x.equals(y)返回是"true",只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是"true"。
- 非空性:x.equals(null),永远返回是"false";x.equals(和x不同类型的对象)永远返回是"false"。
2.equals() 与 == 的区别是什么?
== :判断两个对象的地址是不是相等(即判断两个对象是不是同一个对象)
equals() :判断两个对象是否相等,而这种判断需要分为两种情况,在上一个问题已经说明。
3.hashCode() 的作用是什么?
hashCode() 作用 : 获取哈希码,也称为散列码;实际上是返回一个int整数,而哈希码的作用是确定该对象在哈希表中的索引位置。
具体有关hashCode()介绍可以见这篇博客
hashCode()
定义在java.lang.Object
类中,意味着所有的Java类都包含有hashCode()
函数。但是其实只有创建某个类的散列表时,hashCode()
才是有用的:确定该类的每一个对象在散列表中的位置。
散列表 :指的是Java集合中本质是散列表的类,如HashMap、Hashtable、HashSet。
使用HashSet为例,说明hashCode()的作用
当HashSet中已经拥有1000个元素时,需要向其中插入第1001个元素,需要如何处理?
因为HashSet为Set集合,它不允许有重复元素。
若将第1001个元素和前面1000个元素进行比较,这样的时间复杂度是非常高的。而使用散列表的结构,能较好的解决该问题,通过hashCode()
获取该对象的哈希码,计算出该对象在散列表中的位置,并将其插入,若在该位置已经存在元素,则会进行数据更新,这样一个元素就只会保存一个,满足集合特性。
- 在散列表中,若两个对象相等,它们的散列码一定相等;
- 在散列表中,若两个对象
hashCode()
相等,他们并不一定相等;
4.hashCode() 与 equals() 之间有什么联系?
要说明这两个函数之间的关系,需要按照类的用途来分为2种情况来说明
4.1不会创建“类对应的散列表”
这里所说的不会创建“类对应的散列表”:是说我们不会创建该类的散列表(如HashMap)集合;
在这种情况下,hashCode()
与 equals()
并没有关系;
equals():用于比较两个对象是否相等
hashCode():没有作用
4.2会创建“类对应的散列表”
这里所说的会创建“类对应的散列表”:是说创建该类的散列表(如HashSet)集合
在这种情况下,hashCode()
与 equals()
才有关系;
- 在散列表中,若两个对象相等,它们的
hashCode()
一定相同;- 这里相等指的, 通过
equals()
比较两个对象时返回true
- 这里相等指的, 通过
- 在散列表中,若两个对象
hashCode()
相等,他们并不一定相等;- 因为在散列表中,
hashCode()
相等,即两个键值对的哈希值相等。然而哈希值相等,并不一定能得出键值对相等。(说明“两个不同的键值对,哈希值相等”,这就是哈希冲突)
- 因为在散列表中,
- 同时,在这种情况下,若要判断两个对象是否相等,除了需要覆盖
equals()
之外,还需要覆盖hashCode()
方法,否则equals()
无效。