介绍了Java中的HashSet类,保姆级别介绍,看完提升一个理解档次

  1. 首先是讲了在我们往HashSet中添加自定义类时应该怎么做?

  2. 讲了如何自定义一个类?

  3. 为什么在HashSet中要重写两个方法(hashCode和equals)?这两个方法的作用?

  4. super关键字的作用?

  5. this关键字还可以指代调用该方法的对象/?

  6. instanceof关键字的作用?

  7. toString方法的作用,打印对象的时候得到的居然不是地址?

  8. 我竟然可以往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方法来判断元素是否一样

    }

}

  • 14
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值