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

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

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;

   }

}

1

2

3

4

5

6

进行测试

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);

   }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

测试结果

微信图片_20230701104540.png

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){...}

1

结论: equals(Student student):对equals的声明里传的参数和Student类的类型是一样的,这个函数声明是错误的❌

原因: equals()是Object父类的一个函数,我们是 覆盖equals这个方法,所以这个 函数签名要和Object的函数签名是一样的——Object父类函数传进去的参数的类型是Object,我们需要这样来写⬇️

public boolean equals(Object student){...}

1

2.3.2 渐入佳境➡️善用工具

1️⃣工具之编译器


当正确书写函数声明时, 编译器会左侧出现了一个标志, 表示了我们是override,是在覆盖一个方法

微信图片_20230701104600.png

如果是equals(Student student),相当于自己定义了一个自己的equals,没有进行覆盖,并且编译器也不会有提示

2️⃣工具之Java关键字

微信图片_20230701104619.png

可以在方法上使用关键字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){}

1

2

- 2️⃣因为student是Object类的对象,所以**将其强制转换为Student类的对象**

Student stu = (Student)student;

1

3️⃣完成比较是否相等的逻辑,并将结果返回

该判断仅针对本文中的判断逻辑,因为现实中同名不一定是同一个人

/*此处的equals()其实是调用的String类中的equals

➡️所以,将两个学生类的比较,变成了字符串的比较

如果两个学生的名字所对应的字符串是一样的,即两个学生是一样的

*/

return this.name.equals(stu.name);

1

2

3

4

5

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;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

✔️经过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);

   }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

使用2.1中的测试代码进行测试,得到了我们想要的结果,即成功找到了名为B的学生,在数组students中索引为1的位置,即students[1]

微信图片_20230701104638.png

相关文章
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
69 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
4天前
|
算法 C# 索引
C#线性查找算法
C#线性查找算法!
|
29天前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
32 4
|
1月前
|
机器学习/深度学习 搜索推荐 算法
探索数据结构:初入算法之经典排序算法
探索数据结构:初入算法之经典排序算法
|
1月前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
18 0
|
24天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
8天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
10天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
10天前
|
存储 算法 决策智能
基于免疫算法的TSP问题求解matlab仿真
旅行商问题(TSP)是一个经典的组合优化问题,目标是寻找经过每个城市恰好一次并返回起点的最短回路。本文介绍了一种基于免疫算法(IA)的解决方案,该算法模拟生物免疫系统的运作机制,通过克隆选择、变异和免疫记忆等步骤,有效解决了TSP问题。程序使用MATLAB 2022a版本运行,展示了良好的优化效果。
|
10天前
|
机器学习/深度学习 算法 芯片
基于GSP工具箱的NILM算法matlab仿真
基于GSP工具箱的NILM算法Matlab仿真,利用图信号处理技术解析家庭或建筑内各电器的独立功耗。GSPBox通过图的节点、边和权重矩阵表示电气系统,实现对未知数据的有效分类。系统使用MATLAB2022a版本,通过滤波或分解技术从全局能耗信号中提取子设备的功耗信息。