Java中Comparable,Comparator,Clonaeble接口
一.Comparable接口
Comparable英文翻译过来就是“可比的,对比的”,我们之前没有接触到类和对象的时候,比较大小仅仅是对基本数据类型进行比较,例如int,double.....,如今我们接触了类和对象,在对比大小这方面应该有新的认识
这里我们定义了一个Student类,并且有name和age成员变量和构造方法
再建立了一个Test测试类,创建了student1和student2两个对象
问题:如果我想比较两个对象谁的年龄更大,我要怎么做?
我们都知道student1和student2都是引用,不能直接对他们比较,这里我们就可以引入Comparable接口
首先,让Student实现Comparable接口—>class Student implements Comparable
这个括号里是要比较的类是哪一个
我们ctrl点击Comparable接口,看见里面有个抽象方法compareTo,所以在Student类里一定要重写这个方法
1.比较年龄
2.比较名字(一般是指名字首字母)
注意因为name是String类型,所以直接用接口里的compareTo没办法得到值,所以return后面那个compareTo方法是String的compareTo方法
这里我的compareTo方法比较的是年龄,如果要比较名字就将compareTo方法改成第二种写法
上面这个例子是对两个对象之间的比较,如果我有多个学生,我要怎么做?
我们很轻松的可以想到定义一个Student类型的数组,在之前我们也知道在Java里有个java.util.Arrays这个包里面有个Arrays.sort这个方法可以帮我们整理数组
这里我也是比较年龄,没有比较名字
有的同学想知道这个Arrays.sort实际的代码过程,我们也可以自己实现一个Sort方法,这里我是用冒泡法
写到这里,我们很明显的就看到了Comparable接口的不足之处,它只能对对象的某个特性去比较,如果对象有多个特性,使用Comparable接口是不合适的,所以我们下面会再介绍一个接口来弥补这个不足
二.Comparator接口
依旧以上面的学生类举例,如果我既想要比较学生的年龄,也想要比较学生的名字,就要用到Comparator接口,我们在这里可以先把Comparator接口认为指一种功能
我们将比较年龄的作为一个类,并且实现Comparator这个接口
再将比较名字作为一个类,实现Comparator这个接口
然后我们ctrl点击Comparator接口,看见里面有一个compare抽象方法,所以在上面两个类中都重写了compare方法
因为不同的比较被放在不同的类中,所以要在测试类中运用的话,第一步是创建两个类的对象,用引用来实现比较
同样的,如果是多个学生,也用Arrays.sort来实现,或者用自己的Sort
最后输出:
三.Cloneable接口
Cloneable接口的主要作用就是在原本的有的对象克隆出一份成员变量和方法一样的对象
ctrl同时点击Cloneable可见
在Clonable接口里面什么都没有,那这是什么意思呢? ——>空接口也叫标记接口,如果某个类实现这个接口的话,说明该类可以被克隆
还是以上面的学生类为例
我们既然要克隆,就需要克隆的方法,在Object类中有一个clone方法
(这个图是最大的了😢)
这个方法返回值的类型是Object,并且方法要抛出异常(这个异常目前没有学习,后面会有专门的板块学习),因此在我们的Student类里可以重写这个clone方法
然后在Test类当中定义了一个实例化了一个s1
这里s2输出的age也是15,我们从内存的角度去理解其中发生了什么
当执行clone方法后,拷贝出一份s1指向的对象,并使s2的引用指向拷贝出来的新对象
(注意:拷贝出来的地址是不同的)
在拷贝中还分为浅拷贝和深拷贝
1.浅拷贝
如果我们又定义了一个新的类,也想要被克隆,在Student类中,定义一个这个类的对象,如图
这里我提前让Book实现了Cloneable接口,后面Book类也要实现拷贝
此时内存内部有这个情况
可以看见我们虽然拷贝了new Student(),但是没有new Book(),这被称为浅拷贝
2.深拷贝
如果我们要实现深拷贝,就需要对原本的new Student()中的new Book()进行拷贝
这就需要我们在Student类中的clone方法进行修改
这样不仅仅拷贝了new Student(),也拷贝了new Book(),这种被称为深拷贝
完