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

相关文章
|
2月前
|
测试技术 Android开发 Python
探索软件测试的艺术:从基础到高级安卓应用开发中的自定义视图
【8月更文挑战第29天】在软件开发的世界中,测试是不可或缺的一环。它如同艺术一般,需要精细的技巧和深厚的知识。本文旨在通过浅显易懂的语言,引领读者从软件测试的基础出发,逐步深入到更复杂的测试策略和工具的使用,最终达到能够独立进行高效测试的水平。我们将一起探索如何通过不同的测试方法来确保软件的质量和性能,就像艺术家通过不同的色彩和笔触来完成一幅画作一样。
|
14天前
|
存储 Java
java数据结构,线性表链式存储(单链表)的实现
文章讲解了单链表的基本概念和Java实现,包括头指针、尾节点和节点结构。提供了实现代码,包括数据结构、接口定义和具体实现类。通过测试代码演示了单链表的基本操作,如添加、删除、更新和查找元素,并总结了操作的时间复杂度。
java数据结构,线性表链式存储(单链表)的实现
|
12天前
|
机器学习/深度学习 算法 Java
[算法与数据结构] 谈谈线性查找法~
该文章详细介绍了线性查找法的基本概念与实现方法,通过Java代码示例解释了如何在一个数组中查找特定元素,并分析了该算法的时间复杂度。
|
16天前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
|
1天前
|
人工智能 算法 BI
【算法】 线性DP(C/C++)
【算法】 线性DP(C/C++)
|
2天前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
5 0
|
2月前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
23 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
2月前
|
JSON 测试技术 数据格式
单元测试问题之使用JCode5插件生成测试类如何解决
单元测试问题之使用JCode5插件生成测试类如何解决
74 3
|
2月前
|
Java 测试技术 Spring
单元测试问题之在 JCode5 类中使用 testService如何解决
单元测试问题之在 JCode5 类中使用 testService如何解决
15 2
|
2月前
|
存储
数据结构中的 线性结构和非线性结构
这篇文章介绍了数据结构中的线性结构和非线性结构,其中线性结构包括顺序存储结构和链式存储结构,如数组、队列、链表和栈;非线性结构包括图结构、树结构、二维数组、广义表和多维数组。