集合之HashSet应用思路
一、为什么要重写hashcode和equals两个方法
我们都知道Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类。Ojbect类中有两个方法equals、hashCode,这两个方法都是用来比较两个对象是否相等的。
在未重写equals方法我们是继承了object的equals方法,那里的 equals是比较两个对象的内存地址,显然我们new了2个对象内存地址肯定不一样
- 对于值对象,==比较的是两个对象的值
- 对于引用对象,比较的是两个对象的地址
默认的equals方法同==,但是一般来说我们的对象都是引用对象,要重写equals方法(将对象地址比较重写为对象的值比较)。
所以如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。
二、在什么情况下需要重写hashcode和equals两个方法
想要搞清楚什么情况下重写hashcode和equals方法就的先知道集合在项目中使用场景。
1、集合在项目中使用的场景:首先用户在前端页面填写一个用户信息表单提交(用户表单的会员ID要求不能重复)--------请求通过post方式调用java服务端代码-----服务端的hashset代码在执行add()添加方法的时候就会调用hashcode和equals两个方法判断会员ID是否已存在(所以如果我们对equals方法进行了重写,同时一定要对hashCode方法重写),如果存在则不添加,不存在就将数据添加到数据库。
三、HashSet应用实例
现在有一个学生类登记表单填写,ID、学号、姓名(要求ID不能重复)。HashSet存放Student类对象,需要判断Student对象里面的ID是否存在。这个时候就需要在Student类中将hashcode和equals方法对ID进行判断进行重写。
1、hashcode和equals方法重写在IEDA中生成的快捷方法
2、代码示例
package day15;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
class Student extends Object{
public long id;
public String sn;//学号
public String name;
@Override
//1、重写equals方法对ID对象值是否相等进行判断
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return id == student.id;
}
@Override
//2、重写hashCode方法对ID对象值是否相等进行判断
public int hashCode() {
return (int) (id ^ (id >>> 32));
}
}
public class SetDemo2 {
public static void main(String[]args){
//3、实例化HashSet类的对象
Set set = new HashSet();
//4、实例化Student对象
Student e = new Student();
//5、添加Student对象属性值
e.id = 001;
e.name = "张三";
e.sn = "s1";
//6、将Student对象添加到HashSet集合中
((HashSet) set).add(e);
System.out.println("=====================第一次集合添加对象的值输出=======================");
System.out.println(e.id+e.name+e.sn);
//7、Student对象再次添加ID和第一次添加ID值一样
Student e2 = new Student();
e2.id = 001;
e2.name = "李四";
e2.sn = "s2";
//8、boolean值判断第二次添加已存在的ID值是否存到set集合中
boolean b = set.add(e2);
System.out.println("======================第二次ID是否添加到Set集合中===============:"+b);
//9、Iterator和数组两种方式遍历集合输出对象
System.out.println("==================Iterator和数组两种方式遍历集合输出对象===================");
//10、Iterator输出HashSet集合中对象的值。
Iterator it = set.iterator(); //set调用iterator方法
while (it.hasNext()){
Student s = (Student) it.next(); //Iterator类型转换成Student类型调用Student类中的方法。
System.out.println("===========Iterator方式输出HashSet集合对象存储的值:"+s.id+","+s.name+s.sn);
}
//11、数组方式输出HashSet集合中的对象的值
Object[] obj = set.toArray();
for(int i=0;i<obj.length;i++){
Student s = (Student)obj[i]; //Obj类型转换成Student类型调用Student类中的方法。
System.out.println("---------数组方式输出HashSet集合对象存储的值:"+s.id+","+s.name+","+s.sn);
}
}
}
结果: