【算法与数据结构】3 知行合一,线性查找的自定义类测试

请添加图片描述

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流

本文收录于算法与数据结构体系专栏,本专栏对于0基础者极为友好,欢迎与我一起完成算法与数据结构的从0到1的跨越

在这里插入图片描述

1.前言

☑️首篇详细讲述线性查找法并且对其进行了初步的优化:👉传送门:💖详解什么是算法?什么是线性查找法?💖

☑️第二篇进行了再次优化,讲述了使用泛型这种语言机制来解决避免重复写一个方法的问题:👉传送门:💖线性查找的究极优化💖

⬇️学习了前面的理论,我们应该学会举一反三:在对于不同的类而言,里面的equals()方法具体的实现逻辑可能不同,在第二篇中使用的是Integer作为例子,对于Java语言而言,已经帮助实现了Integer类的equals()方法,包括8个基本类型对应的包装类或者String类等通常使用的类,Java语言都已经帮我们实现了equals()方法
🔺当我们使用自己定义的类的时候,是需要自己去将equals()的逻辑实现出来的,那么一起来学习如何实现吧👇

2.使用自定义类测试

2.1⛏创建Student类并测试

  • 创建Student类
public class Student {        //Student类
    private String name;
    public Student(String name){
        this.name = name;
    }
}
  • 进行测试
public class LinearSearch {
    private LinearSearch(){}
    public static <E> int search(E[] data, E target){
        for(int i = 0; i < data.length; i ++)
            if(data[i].equals(target))
                return i;
        return -1;
    }
    public static void main(String[] args){    //进行测试
        Student[] students = {new Student("A"),
                              new Student("B"),
                              new Student("C")};
        Student b = new Student("B");
        int res3 = LinearSearch.search(students, b);
        System.out.println(res3);
    }
}
  • 测试结果
    在这里插入图片描述

2.2 🔎剖析测试结果

  • 🔵代码描述: students数组是一个Student类的数组,里面new了三个Student类的对象,分别为A、B、C,然后使用LinearSearch的search()方法——参数为数组students和b,即查找students中是否有名为"B"的学生
  • 🔴结果描述: 查询结果是-1,即不存在学生B,很明显,查询结果是有误的
  • 🟢结果剖析: 查询结果是-1,是因为 equals()方法默认比较的是两个类对象的地址,而在我们上面代码的逻辑中,我们 更希望的是比较两个类对象所对应的字符串 ——为了实现这个逻辑,我们就必须自己 自定义Student的这个类中的这个equals()

2.3 自定义equals()

2.3.1 初窥门径➡️错误的函数声明

public boolean equals(Student student){...}
  • 结论: equals(Student student):对equals的声明里传的参数和Student类的类型是一样的,这个函数声明是错误的❌
  • 原因: equals()是Object父类的一个函数,我们是 覆盖equals这个方法,所以这个 函数签名要和Object的函数签名是一样的——Object父类函数传进去的参数的类型是Object,我们需要这样来写⬇️
public boolean equals(Object student){...}

2.3.2 渐入佳境➡️善用工具

  • 1️⃣工具之编译器

    • 正确书写函数声明时, 编译器会左侧出现了一个标志, 表示了我们是override,是在覆盖一个方法
      在这里插入图片描述
    • 如果是equals(Student student),相当于自己定义了一个自己的equals,没有进行覆盖,并且编译器也不会有提示
  • 2️⃣工具之Java关键字

    • 可以在方法上使用关键字Override,这样如果在需要覆盖却没有覆盖的时候,编译器就会报错
      在这里插入图片描述
      在这里插入图片描述
    • ❓为什么会报错?因为无法找到与public boolean equals(Student student)的函数签名一样的equals(),编译器没有检查到我们是在覆盖一个方法。
    • ✅如果改成public boolean equals(Object student),编译器就会找到Student的一个父类,即Object类中有与其函数签名一样的equals(),则这个覆盖就是正确的

2.3.3 略有小成 ➡️完成equals()

  • 1️⃣声明
@Override
    public boolean equals(Object student){}
- 2️⃣因为student是Object类的对象,所以**将其强制转换为Student类的对象**
Student stu = (Student)student;
  • 3️⃣完成比较是否相等的逻辑,并将结果返回
    • 该判断仅针对本文中的判断逻辑,因为现实中同名不一定是同一个人
/*此处的equals()其实是调用的String类中的equals
➡️所以,将两个学生类的比较,变成了字符串的比较
如果两个学生的名字所对应的字符串是一样的,即两个学生是一样的
*/
return this.name.equals(stu.name);
  • 4️⃣整体逻辑如上⬆️,不过我们仍需要添加一些判断, 因为将Object类型的对象student 强制转换为Student类的对象,可能会抛异常或者无法强制转换
//【判断1】:this,即当前这个类的对象,是否就是Student类的对象,它们的地址是否一样
if(this == student)
 	/*
 	如果判断结果为一样,
 	那么比较的就是同一个对象,就不需要强制转换,true
 	*/
	return true;

//【判断2】:如果判断1是false,那么就判断传来的student是不是一个空对象
if(student == null)
	/*当前的Student类的对象肯定是非空的,如果传来的student是空对象,那么直接false*/
	return false;
	
//【判断3】:判断强制转换是否成立
	/*
	this.getClass()即当前这个类对象所对应的类到底是什么,其实就是Student类
	判断this.getClass是否等于传来的student这个对象所对应的类
	如果不相等,即二者不属于同一个类,直接false
	*/
if(this.getClass() != student.getClass())
	return false;

✔️经过4️⃣里的3个判断,如果都通过了,即传的student不为空,且确实是Student类的对象,那么就可以安全的进行强制转换的操作2️⃣

2.3.4 融会贯通➡️完整的equals()

public class Student {
    private String name;
    public Student(String name){
        this.name = name;
    }
    @Override
    public boolean equals(Object student){

        if(this == student)
            return true;

        if(student == null)
            return false;

        if(this.getClass() != student.getClass())
            return false;

        Student another = (Student)student;
        return this.name.equals(another.name);
    }
}
  • 使用2.1中的测试代码进行测试,得到了我们想要的结果,即成功找到了名为B的学生,在数组students中索引为1的位置,即students[1]
    在这里插入图片描述请添加图片描述
  • 34
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 27
    评论
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员一修

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值