接口使用实例(自定义类型排序和深浅拷贝)

Posted 爱敲代码的三毛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了接口使用实例(自定义类型排序和深浅拷贝)相关的知识,希望对你有一定的参考价值。


一、Comparable 接口

1.sort 方法

我们知道数组有一个 sort 方法是用来排序的,使用也很简单可以直接调用它来排序基本类型的数组。

代码示例:

在这里插入图片描述

运行结果

在这里插入图片描述
那么如果用它来排序一个自定义类型,能不能排序呢?

代码示例:

在这里插入图片描述

运行结果:

在这里插入图片描述
这里抛出一个异常,说学生这个类型不能转换 java.lang.Comparable,那么这个Comparable到底是个啥呢?

来看一下源码
也就是说我们要把 Student 强制转换为 Comparable 再来调用Comparable 里面的 compareTo方法来进行比较。

在这里插入图片描述

仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确.
而两个学生对象的大小关系怎么确定呢,现在需要我们自己来指定,

2.compareTo

我们调用 sqrt 来进行自定义类型的比较,但是它并不知道要通过什么来比较。年龄还是姓名?
所以我们要指定比较方法
让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法
代码示例:

在这里插入图片描述
运行结果

在这里插入图片描述
那么如果要用姓名比较,也要重写compareTo方法,如果以后引用类型要进行比较一定要用 compareTo方法,而且一定要实现Comparable 接口

在这里插入图片描述
运行结果

在这里插入图片描述
在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.

然后比较当前对象和参数对象的大小关系(按分数来算).
如果当前对象应排在参数对象之前, 返回小于 0 的数字;
如果当前对象应排在参数对象之后, 返回大于 0 的数字;
如果当前对象和参数对象不分先后, 返回 0

3.小结

compareTo其实就是一个比较规则,如果以后自定义类型要进行比较一定要重写compareTo这个比较规则。但是如果这个比较规则已经被很多人使用,你突然想换个比较规则,如果修改比较规则必然会造成损失,所以这个方方法对类的侵入性太强了,并不是特别好

二、Comparator 接口

刚刚我们说 Comparable 对类的侵入性太强了,但有另外一个接口它十分灵活。就是Comparator

代码示例:

我们写了两个类,分别实现了 Comparator 这个接口,一个是用年龄比较,一个是用姓名比较。我们叫做比较器。

在这里插入图片描述

在这里插入图片描述
再来看原来的代码,我们的Student并没有实现任何接口,也没有重写compareTo 方法。
只是实例化了刚刚上面两个比较器,在用sort比较时,传过去了两个参数,一个是要排序的数组,一个是我们写的比较器对象。

在这里插入图片描述
运行结果:

在这里插入图片描述
Comparator 接口,如果要进行比较只需要根据自己的需要写一个比较器就好了,并不像第一个接口那样直接写死了。

三、Clonable 接口

1.Clonable 使用

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现Clonable接口

1.实现Clonable接口
2.记住要处理异常
3.重写 Object 的 clone 方法

代码示例:

在这里插入图片描述
运行结果:

在这里插入图片描述
此时内存中的存储

在这里插入图片描述

2.浅拷贝

怎么来理解深拷贝和浅拷贝呢?

来看一下浅拷贝,我们在刚才的例子中在Student中实例化了一个Money类

在这里插入图片描述

运行结果

在这里插入图片描述
我们发现当我们修改 student 的money的值的同时,student1的值也被修改了,这并不是我们想要的拷贝效果,那么此时这就是一个浅拷贝。

此时的内存图

在这里插入图片描述

3.深拷贝

刚刚那个例子是浅拷贝,那么怎么实现深拷贝呢?
只需要在刚刚那个例子中修改,Student里面的clone方法即可。
先拷贝一个stydent,再把原来拷贝的对象里面的tmp也拷贝一份,让拷贝出来的新对象里面的tmp指向拷贝出来的tmp,就实现了深拷贝。

在这里插入图片描述
运行结果

在这里插入图片描述

此时内存图

在这里插入图片描述


完!

以上是关于接口使用实例(自定义类型排序和深浅拷贝)的主要内容,如果未能解决你的问题,请参考以下文章

java自定义类型 比较排序 Comparator接口

golang 自定义接口体(与其他语言对象类似)

C# 自定义类型数组的排序

hadoop 学习自定义排序

js深浅拷贝

查询自定义帖子类型并按自定义帖子类型排序