【算法与数据结构】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

相关文章
|
7天前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
40 9
 算法系列之数据结构-二叉树
|
4天前
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
28 3
 算法系列之数据结构-Huffman树
|
6天前
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
47 22
|
1月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
92 29
|
15天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
本研究基于MATLAB 2022a,使用GRU网络对QAM调制信号进行检测。QAM是一种高效调制技术,广泛应用于现代通信系统。传统方法在复杂环境下性能下降,而GRU通过门控机制有效提取时间序列特征,实现16QAM、32QAM、64QAM、128QAM的准确检测。仿真结果显示,GRU在低SNR下表现优异,且训练速度快,参数少。核心程序包括模型预测、误检率和漏检率计算,并绘制准确率图。
83 65
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
|
2天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于生物地理算法的MLP多层感知机优化matlab仿真
本程序基于生物地理算法(BBO)优化MLP多层感知机,通过MATLAB2022A实现随机数据点的趋势预测,并输出优化收敛曲线。BBO模拟物种在地理空间上的迁移、竞争与适应过程,以优化MLP的权重和偏置参数,提升预测性能。完整程序无水印,适用于机器学习和数据预测任务。
|
1天前
|
资源调度 算法 数据可视化
基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF
本项目基于MATLAB2022A实现IEKF迭代扩展卡尔曼滤波算法的数据跟踪仿真,对比EKF和UKF的性能。通过仿真输出误差收敛曲线和误差协方差收敛曲线,展示三种滤波器的精度差异。核心程序包括数据处理、误差计算及可视化展示。IEKF通过多次迭代线性化过程,增强非线性处理能力;UKF避免线性化,使用sigma点直接处理非线性问题;EKF则通过一次线性化简化处理。
|
3天前
|
算法 数据安全/隐私保护
基于二次规划优化的OFDM系统PAPR抑制算法的matlab仿真
本程序基于二次规划优化的OFDM系统PAPR抑制算法,旨在降低OFDM信号的高峰均功率比(PAPR),以减少射频放大器的非线性失真并提高电源效率。通过MATLAB2022A仿真验证,核心算法通过对原始OFDM信号进行预编码,最小化最大瞬时功率,同时约束信号重构误差,确保数据完整性。完整程序运行后无水印,展示优化后的PAPR性能提升效果。
|
6天前
|
机器学习/深度学习 数据采集 算法
基于PSO粒子群优化的CNN-LSTM-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-LSTM-SAM网络时间序列预测算法。使用Matlab2022a开发,完整代码含中文注释及操作视频。算法结合卷积层提取局部特征、LSTM处理长期依赖、自注意力机制捕捉全局特征,通过粒子群优化提升预测精度。适用于金融市场、气象预报等领域,提供高效准确的预测结果。
|
6天前
|
算法 数据安全/隐私保护
基于Big-Bang-Big-Crunch(BBBC)算法的目标函数最小值计算matlab仿真
该程序基于Big-Bang-Big-Crunch (BBBC)算法,在MATLAB2022A中实现目标函数最小值的计算与仿真。通过模拟宇宙大爆炸和大收缩过程,算法在解空间中搜索最优解。程序初始化随机解集,经过扩张和收缩阶段逐步逼近全局最优解,并记录每次迭代的最佳适应度。最终输出最佳解及其对应的目标函数最小值,并绘制收敛曲线展示优化过程。 核心代码实现了主循环、粒子位置更新、适应度评估及最优解更新等功能。程序运行后无水印,提供清晰的结果展示。

热门文章

最新文章