-
首先是讲了在我们往HashSet中添加自定义类时应该怎么做?
-
讲了如何自定义一个类?
-
为什么在HashSet中要重写两个方法(hashCode和equals)?这两个方法的作用?
-
super关键字的作用?
-
this关键字还可以指代调用该方法的对象/?
-
instanceof关键字的作用?
-
toString方法的作用,打印对象的时候得到的居然不是地址?
-
我竟然可以往HashSet中存入两个一样的元素?
答案见代码注释!如果可以的话顺便教教我怎么更改注释颜色和大小等,有插件吗?我的idea找不到改注释的选项
package JiaXinTest;
import javax.xml.namespace.QName;
import java.util.*;
public class Student {
/*
为了保证HashSet正常工作,要求在将一个对象存入HashSet集合石时
重写该对象的Object类中的hashCode方法和equals()方法
但是为什么不是调用HashSet本身的hashCode方法和equals()方法,而是调用被存入对象的
hashCode方法和equals()方法呢?
对于自定义类而言,Java 的 Object 类提供的默认 hashCode() 和 equals() 不好使
因此,当我们需要将自定义类的对象放入 HashSet 这样的集合中,并要求元素不重复时,就需要重写这两个方法
当向 HashSet 中添加元素时,它会首先调用该对象(元素)的 hashCode() 方法来计算一个哈希码,方便后面根据hash码来快速查询元素
然后调用该对象的equals来判断是否值相同
那么如何自定义一个类呢?
1:定义类属性
2:重写构造方法
*/
String id;
String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
@Override
public int hashCode() {
return id.hashCode();
}
/*
super的作用?
答:调用父类(Object的方法)
*/
/*
直接用equal不就可以确定元素是否相同了嘛,为什么还要用hashCode,用来确定元素位置?
为什么要确定位置?在Set中元素位置不是随机的嘛?
答:hash还是有存在的必要的,当元素存入时,要通过hash来映射元素的位置,以便在hash表中
快速找到元素位置
位置还是要确定的,当你需要某个元素的时候,hash表可以通过hash码快速找到该元素,而不用遍历全表
*/
@Override
public boolean equals(Object obj) {
{
if (this == obj) {//这里的this是什么意思? 指调用equals方法的对象
//拿着新元素的hash值和所有元素对比?
return true;
}
if (!(obj instanceof Student)) {//instanceof是什么意思? 调用该方法的对象是否是Student类或其子类的实例
return false;
}
Student stu = (Student) obj;//把obj对象强转为Student类型
//为什么要这样做? 为了访问Student类特有的属性 那一开始就用Student类型可以嘛?
boolean b = this.id.equals(stu.id);
return b;
}
}
public static void main(String[] args) {
Student student = new Student("1", "nan");
// System.out.println(student.toString());
// System.out.println(student);
/*
为什么我在这里直接打印Student对象得到的是和toString一样的结果呢?
不应该是得到一个对象的引用地址嘛?
答:在打印一个对象的时候,其实是调用了该对象的toString方法,而我在这里重写了该方法
所以得到的就是和ToString一样的结果
*/
//创建HashSet集合
HashSet hashSet = new HashSet();
hashSet.add(student);
// hashSet.add(student); 这里我重复添加了一样的对象,所以java虚拟机不会执行两次
//但如果新建一个对象然后存入一样的信息会怎么样呢?
Student str3 = new Student("1", "nan");
hashSet.add(str3);
//存入了两个值一样的元素,但我们知道hashset是不允许重复元素的。
//因为我们没有重写Student类的hashCOde方法和equal方法来判断元素是否一样
Student student1 = new Student("2", "ting");
hashSet.add(student1);
System.out.println(hashSet);//注意为什么hashSet可以直接打印得到元素,而ArrayList却要通过遍历呢?
// 答:因为HashSet重写了ToString方法,该方法调用了每个元素自身的ToString方法。
//在类中重写Student类的hashCOde方法和equal方法来判断元素是否一样
}
}