Java的Comparable,Comparator和Cloneable三大接口详解
作者:反内码者 发布时间:2023-07-14 11:18:48
1、比较器
①比较器的引入
a.首先,当我们单一地比较某一种数据类型的数组时,可以直接用Arrays.sort()进行实现
b.而当我们同时含有多个参数时,并没有告诉我们按照什么来进行排序,此时,若是用Arrays.sort()就会出现报错的情况
基于这种情况,我们了解到,若是要将自定义类型进行大小比较 ,就要引入能够实现比较的接口,下面我们介绍Comparable和Comparator这两种比较器
1.1Comparable接口
①实现Comparable接口的操作
②通过Comparable接口实现年龄的排序
③通过Comparable来实现名字的排序(注意名字是引用类,比较时应该是用compareTo()来进行)
④升序降序
由于最终是利用的Arrays.sort()进行的比较,该方法底层是升序的操作,若是想转换为降序,只需要将重写的compareTo()方法中两项互换位置即可
变为降序后代码运行结果:
⑤缺点!!!
Comparable对类的倾入性很强。由上面我们可知,要想比较新的类型就要更改compareTo()中的类型重新进行比较,这个在以后的工作中极大可能会使整个代码出现逻辑问题,可读性问题,因此我们引入下一类很灵活,倾入性不强的Comparator接口
⑥整体代码如下:
import java.util.Arrays;
class Student implements Comparable<Student> {
public int age;
public String name;
public double score;
public Student(int age,String name,double score){
this.age=age;
this.name=name;
this.score=score;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score=" + score +
'}';
}
public static void main3(String[] args) {
Student student1=new Student(12,"张三",98.0);
Student student2=new Student(18,"李四",97.9);
//if(student1.compareTo(student2)>0)返回1;根据下面的方法进行进一步的返回
System.out.println(student1.compareTo(student2));
}
public static void main(String[] args) {
Student []student=new Student[3];
student[0]=new Student(36,"zhangsan",98.0);
student[1]=new Student(18,"lisi",97.9);
student[2]=new Student(27,"wangwu",65.3);
System.out.println(Arrays.toString(student));
Arrays.sort(student);
System.out.println(Arrays.toString(student));
}
public static void main1(String[] args) {
int []array=new int []{2,5,3,6,8};
System.out.println(Arrays.toString(array));
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
@Override
//谁调用这个方法,谁就是this
public int compareTo(Student o) {
//return this.age-o.age;
return o.name.compareTo(this.name);
}
}
1.2Comparator接口
①实现Comparable接口的操作:
②通过该接口实现的姓名的比较:
③升序降序
执行后的结果:
④优点
灵活,对类的倾入性不强
⑤整体代码如下:
import java.util.Arrays;
import java.util.Comparator;
class Student {
public int age;
public String name;
public double score;
public Student(int age, String name, double score) {
this.age = age;
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score=" + score +
'}';
}
}
class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age-o2.age;
}
}
class ScoreComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return (int)(o1.score-o2.score);
}
}
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
}
public class Test {
public static void main2(String[] args) {
Student students1 = new Student(1,"bit",98.9);
Student students2 = new Student(2,"abc",88.9);
/* if(students1.compareTo( students2) > 0) {
}*/
//System.out.println(students1.compareTo( students2));
AgeComparator ageComparator = new AgeComparator();
System.out.println(ageComparator.compare(students1,students2));
}
public static void main(String[] args) {
Student[] student = new Student[3];
student[0] = new Student(12,"lisi",98.9);
student[1] = new Student(6,"zangwu",88.9);
student[2] = new Student(18,"whangsan",18.9);
System.out.println(Arrays.toString(student));
AgeComparator ageComparator = new AgeComparator();
ScoreComparator scoreComparator = new ScoreComparator();
NameComparator nameComparator = new NameComparator();
Arrays.sort(student,nameComparator);//默认是从小到大的排序
System.out.println(Arrays.toString(student));
}
public static void main1(String[] args) {
int[] array = {1,21,3,14,5,16};
System.out.println(Arrays.toString(array));
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}
2、Cloneable接口
①如何实现Cloneable接口:
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝". 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException
异常。
a.实现Cloneable接口
b.重写Cloneable方法
c.抛异常,强制类型转换
②面试中常问问题:
你知道Cloneable接口吗?为什么它是一个空接口,它有什么作用呢?
空接口,标志接口,代表这个类是可以被克隆的
③克隆的原理图:
④整体代码的实现:
class Person implements Cloneable{
public int age;
public void eat(){
System.out.println("吃!");
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
person.age=13;
Person person2=(Person)person.clone();
System.out.println(person2);
System.out.println(person);
System.out.println("===========");
person2.age=14;
System.out.println(person);
System.out.println(person2);
}
}
2.1深拷贝和浅拷贝
①深浅拷贝:
决定是深拷贝还是浅拷贝,并不是方法的用途,而是代码的实现
②浅拷贝示例
浅拷贝代码如下:
class Money implements Cloneable{
public double m = 12.5;
}
class Person implements Cloneable{
public int age;
public Money money = new Money();
public void eat() {
System.out.println("吃!");
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person tmp = (Person)super.clone();
return tmp;
}
}
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Person person2 = (Person)person.clone();
System.out.println(person.money.m);
System.out.println(person2.money.m);
System.out.println("=====================");
person2.money.m = 98.5;
System.out.println(person.money.m);
System.out.println(person2.money.m);
}
}
③深拷贝示例:(将tmp中的money也进行拷贝)
深拷贝代码如下:
class Money implements Cloneable{
public double m = 12.5;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public int age;
public Money money = new Money();
public void eat() {
System.out.println("吃!");
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person tmp = (Person)super.clone();
tmp.money = (Money) this.money.clone();
return tmp;
//return super.clone();
}
}
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Person person2 = (Person)person.clone();
System.out.println(person.money.m);
System.out.println(person2.money.m);
System.out.println("=====================");
person2.money.m = 98.5;
System.out.println(person.money.m);
System.out.println(person2.money.m);
}
}
来源:https://blog.csdn.net/weixin_58850105/article/details/123438815


猜你喜欢
- 在进行一些小型APP的开发,或者是对拍照界面没有自定义要求时,我们可以用调起系统相机的方式快速完成拍照需求和不需读写权限进行读写操作的方案一
- filter自定义过滤器 增加了 对验证码的校验package com.youxiong.filter;import com.y
- 简述:JRebel是一款JVM插件,它使得Java代码修改后不用重启系统,立即生效。IDEA上原生是不支持热部署的,一般更新了 Java 文
- 什么是jdkjdk是什么呢?jdk的是java development kit的缩写,意思是java程序开发的工具包。也可以说jdk是jav
- 前言我们了解数组这个概念之前,我们先思考下面几个问题。如果我们需要两个数据,那么直接创建两个变量即可int a;int b;如果需要五个数据
- Java 执行 JS 脚本工具用途:为了便于系统扩展,提供了 JS 脚本的功能,可以通过在系统中执行脚本来获得更复杂的功能。例如:系统提供了
- Mybatis的Dao层实现传统开发方式编写UserDao接口public interface UserDao {  
- Java注解(annotation)简单上手反射reflect:https://www.jb51.net/article/221282.ht
- 由于公司项目的需求,需要绘制一条竖直的间断线作为分割线。这个可坑了爹了,以前只搞过水平的间断线,只要通过shape也可以简单的画出来,但是千
- 本文实例讲述了C#快速排序算法。分享给大家供大家参考。具体实现方法如下:public static int[] QuickSort(int[
- 工作中许多代码中用到枚举(enum),更用到了需要继承的枚举,由于C#的枚举不允许被继承(但允许继承自int/float等类型,这个不是我要
- 安装jdk1.7.0_04后,同时设置环境变量,并且source。可是java -version查看后,还是只能查看到jdk1.6和jdk1
- 本文实例讲述了Java获取时间年、月、日的方法。分享给大家供大家参考。具体实现方法如下:package com.date.demo; imp
- Junit这种老技术,现在又拿出来说,不为别的,某种程度上来说,更是为了要说明它在项目中的重要性。 凭本人的感觉和经验来说,在项目中完全按标
- 前言: 在命令行中输入可以输入各类参数,本文将针对这些参数做一个小结。基于命令行输入参数测试程序如下:import java.util.Ar
- 在Android Studio项目中引用第三方jar包的方法:步骤:1、在build.gradle文件中添加如下代码:备注:要添加在Andr
- XY个人记SparkSQL是spark的一个模块,主入口是SparkSession,将SQL查询与Spark程序无缝混合。DataFrame
- 1.android中利用webview调用网页上的js代码。Android 中可以通过webview来实现和js的交互,在程序中调用js代码
- 1、final修饰类被final修饰的类不能被继承,因此final类的成员方法也不能被覆写,被final关键字修饰的类没有子类,因此类的实现
- 我们在k8s集群成功搭建了Prometheus服务。今天,我们将在springboot2.x中使用prometheus记录指标。一、我们需要