Java学习【接口的使用实例,浅克隆与深克隆】

Java学习【接口的使用实例,浅拷贝与深拷贝】

  • Comparable接口
    • String类型比较
    • 多个对象的比较
  • Comparator接口
  • Cloneable接口
    • 浅拷贝
    • 深拷贝

Comparable接口

当我们想要比较两个基本数据类型的大小时直接用 > , < , = 就可以了,那么如果是自定义的类要根据什么规则进行比较呢?这就用到了Comparable接口,接口中定义的就是一种规范,通过重写接口中的compareTo方法,定义比较规则,就实现了自定义类型的比较

//调用接口
class Man implements Comparable<Man>{
    public String name;
    public int age;
    public Man(String name,int age){
        this.name = name;
        this.age = age;
    }
	
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
//重写接口方法
    @Override
    public int compareTo(Man m) {
        return this.age - m.age;
    }
}
public class Text01 {
    public static void main(String[] args) {
        Man man1 = new Man("li",18);
        Man man2 = new Man("wang",20);
        System.out.println(man1.compareTo(man2));//输出-2
    }
}

在这里插入图片描述

谁调用compareTo方法,this就代表谁

在这里插入图片描述

String类型比较

上面比较的age是整型,可以相减,那如果是String 类型呢
在这里插入图片描述
可以看出,Java中的String类也实现了Comparable接口,同时也重写了compareTo方法
在这里插入图片描述
那么我们只需要调用就可以了

@Override
    public int compareTo(Man m) {
        return this.name.compareTo(m.name);
    }

多个对象的比较

import java.util.Arrays;

class Man implements Comparable<Man>{
    public String name;
    public int age;
    public Man(String name,int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Man m) {
        return this.name.compareTo(m.name);
    }

}
public class Text01 {
    public static void main(String[] args) {
        Man man1 = new Man("li",18);
        Man man2 = new Man("wang",20);
        Man man3 = new Man("zhang",22);
        Man[] men = {man1,man2,man3};
        //使用Arrays类的sort方法对数组进行排序
        Arrays.sort(men);
        System.out.println(Arrays.toString(men));
    }
}

运行结果:
在这里插入图片描述
可以看出,是按照重写后的compareTo方法进行排序的

在这里插入图片描述
这一次程序报错了,类型转换的错误
在这里插入图片描述
当点到出错的地方来看
在这里插入图片描述
当把之前的注释取消,源码底层就会把Man强转为Comparable,调用compareTo方法,而此时由于compareTo重写了,就会调用重写后的方法,排序也会根据重写之后的compareTo方法进行排序。

简单模拟一下Array.sort对自定义类型的排序

public static void main(String[] args) {
        Man man1 = new Man("li",18);
        Man man2 = new Man("wang",20);
        Man man3 = new Man("zhang",22);
        Man[] men = {man1,man2,man3};
        //使用Mysort方法对数组进行排序
        Mysort(men);
        System.out.println(Arrays.toString(men));
    }
public static void Mysort(Comparable[] comparables){
        for(int i = 0;i < comparables.length - 1;i++){
            for(int j = 0;j< comparables.length - 1 - i;j++){
                //如果后面的元素比前面的元素小,则交换它们的位置
                if(comparables[j].compareTo(comparables[j+1]) > 0){
                    Comparable temp = comparables[j];
                    comparables[j] = comparables[j+1];
                    comparables[j+1] = temp;
                }
            }
        }
    }

所以当调用Arrays.sort给自定义的类型进行排序的时候,也必须实现Comparable的接口

但是无论是比较age还是name,用以上方法都比较固定,不够灵活,为了解决这个问题,我们来介绍下一个接口

Comparator接口

public class BrandComparator implements Comparator<Car>{

    @Override
    public int compare(Car o1, Car o2) {
        return o1.getBrand().compareTo(o2.getBrand());
    }
}

调用接口之后重写compare方法

public static void main(String[] args){
        Car car1 = new Car("benz","black",200);
        Car car2 = new Car("audi","white",250);
        Car[] cars = {car1,car2};
        //使用Comparator接口的compare方法
        BrandComparator brandComparator = new BrandComparator();
        //传入比较器
        Arrays.sort(cars,brandComparator);
        //toString方法
        System.out.println(Arrays.toString(cars));
        for(Car car:cars){
            System.out.println("品牌:" + car.getBrand());
            System.out.println("颜色:" + car.getColor());
            System.out.println("速度:" + car.getSpeed());
        }
    }

也可以直接调用方法,单独比较

BrandComparator brandComparator = new BrandComparator();
        int res = brandComparator.compare(car1,car2);
        System.out.println(res);

这样就比较灵活,想要根据哪个属性比较,就定义一个类去实现Comparator接口,再定义比较的规则

Cloneable接口

public class Person {
    public String name;
    public int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

创建一个Person类之后,实现对象的克隆
在这里插入图片描述
虽然Person类里面没有clone方法,但是Object类里面有,每一个类都默认继承与Object类,但此时还是报错了,这就需要在Person类中重写clone方法
在这里插入图片描述

@Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

加上之后还是错的,原因是,自定义类型想要进行克隆还要实现Cloneable接口
在这里插入图片描述
点进源码发现Cloneable接口没有写任何方法,是一个空接口,空接口也叫做标记接口,表示当前类是可以被克隆的
在这里插入图片描述
之后还要处理一下异常,再对返回值类型进行强转,因为此时返回的是Object类型的,这样就可以正常执行了

public static void main(String[] args) throws CloneNotSupportedException{
        Person person1 = new Person("张三", 20);
        Person person2 = (Person) person1.clone();
    }

在这里插入图片描述
具体过程就是创建person1对象之后,再克隆一份数据,创建person2,把克隆出的数据赋值给person2

浅拷贝

在这里插入图片描述
在原来的基础上再加上一个Money类,此时再对克隆后的值进行修改
在这里插入图片描述
在这里插入图片描述
可以看出,当把person1的money修改之后,两个是都会发生改变的,这种就叫做浅拷贝
在这里插入图片描述
此时就是只克隆了Person的对象,没有克隆Money的对象

深拷贝

如果想要Money也进行克隆,就需要实现Cloneable接口,同时重写clone方法

class Money implements Cloneable{
    public double money = 9.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Person类的clone也要重写
在这里插入图片描述
在这里插入图片描述
Person克隆之后,Money也进行克隆,就是深拷贝
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/636183.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言-牛客-实现四舍五入

欢迎来到Harper.Lee的学习小世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客主页 想要一起进步的uu欢迎来后台找我哦&#xff01; 本篇博客总结C语言刷题的相关笔记~~~~ #牛客–实现四舍五入 题目描述&#xff1a;随机输入浮点数&#xff0c;输出四舍五入后的整数…

MySQL 主备环境搭建 docker

MySQL 主备环境搭建 docker 拉取docker镜像 sudo docker pull mysql:8.0 启动容器 docker run -p 3339:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD123456 -d mysql:8.0docker run -p 3340:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD123456 -d mysql:8.0配置 M…

vue.js对接海康威视摄像头web开发包

一、登录海康开放平台下载web开发包&#xff0c;下载需要先登录海康账号&#xff0c;没有的需先注册一个。 这里的appkey、ip、port、secret 和cameraIndexCodeasd是自己去申请的 appkey: "****", ip: "****", port: **, secret: "****", //必填…

【论文速读】|探索ChatGPT在软件安全应用中的局限性

本次分享论文&#xff1a;Exploring the Limits of ChatGPT in Software Security Applications 基本信息 原文作者&#xff1a;Fangzhou Wu, Qingzhao Zhang, Ati Priya Bajaj, Tiffany Bao, Ning Zhang, Ruoyu "Fish" Wang, Chaowei Xiao 作者单位&#xff1a;威…

与优秀者同行,“复制经验”是成功的最快捷径

富在术数不在劳身&#xff0c;利在局势不在力耕。我们始终相信&#xff0c;与优秀者同行&#xff0c;“复制经验”才是走向成功的最快“捷径”! 酷雷曼合作商交流会 作为酷雷曼合作商帮扶体系里的重要一环&#xff0c;合作商交流会是总部专门为合作商们搭建的一个博采众长、相…

基于svm的水果识别

1、程序界面介绍 该程序GUI界面包括待检测水果图片加载、检测结果输出、清空可视化框等。其中包括训练模型、加载图片、重置、识别检测按钮。 程序GUI界面 识别玉米识别西瓜 分类器识别水果基本原理&#xff1a; 由于每种水果的外形存在很大差异&#xff0c;比如西瓜与玉米&…

【class14】创建自己的OCR系统

【class14】 上节回顾 在上节课中&#xff0c;我们主要了解了OCR的实现原理。 简单来说&#xff0c;OCR技术就是提取文档/图像中的文字。 接下来我们将进入实战&#xff0c;搭建属于自己的OCR系统&#xff5e;为了更高效地学习&#xff0c;我们分为以下几步完成&#xff1a;…

【调试笔记-20240516-Windows-使用VS2019编译edk2(上)】

调试笔记-系列文章目录 调试笔记-20240516-Windows-使用VS2019编译edk2&#xff08;上&#xff09; 文章目录 调试笔记-系列文章目录调试笔记-20240516-Windows-使用VS2019编译edk2&#xff08;上&#xff09; 前言一、安装开发工具1. 安装 VS20192. 安装 Python 3.103. 安装 …

一图看懂 | 蓝卓医化行业解决方案

随着“创新药”首次出现在政府工作报告中&#xff0c;医药工业各个细分赛道都迎来了关键突破期&#xff0c;其中化学药品制剂作为所有药品中数量、品种最多的类别&#xff0c;也是居民日常生活中使用最广泛的类别&#xff0c;推动医药化工行业数字化能力&#xff0c;对于发展新…

uniapp宠物咖门店连锁会员制宠物寄养系统 微信小程序-

随着人们生活水平的提高&#xff0c;越来越多的人喜欢给自己或是家里的老人小孩养一只可爱的宠物&#xff0c;满足宠物的需要也就成为了许多爱宠人士每天苦恼的事情&#xff0c;去哪可以选购到健康合格的宠物食品&#xff1f;去哪能给宠物看病&#xff1f;去哪能给脏了的宠物美…

MongoDB基础入门到深入(七)建模、调优

文章目录 系列文章索引十一、MongoDB开发规范十二、MongoDB调优1、三大导致MongoDB性能不佳的原因2、影响MongoDB性能的因素3、MongoDB性能监控工具&#xff08;1&#xff09;mongostat&#xff08;2&#xff09;mongotop&#xff08;3&#xff09;Profiler模块&#xff08;4&a…

气膜体育场馆的迅速发展与应用前景—轻空间

近年来&#xff0c;随着国家大力提倡体育运动和全民健身&#xff0c;国内体育场馆的数量和规模呈现出迅速扩张的趋势。气膜场馆凭借其低成本、快速建造和环保绿色的优势&#xff0c;成为中国体育场馆发展的重要组成部分。据《中国体育气膜白皮书》统计&#xff0c;截至2022年&a…

2024上海国际化工自动化仪器仪表展览会

2024上海国际化工自动化仪器仪表展览会 2024 Shanghai International Chemical Automation Instrument Exhibition 时间&#xff1a;2024年12月11-13日 地点&#xff1a;上海新国际博览中心 详询主办方陆先生 I38&#xff08;前三位&#xff09; I82I&#xff08;中间四位…

STM32_HAL_RTC时钟

1. RTC 时钟简介 STM32F407 的实时时钟&#xff08;RTC&#xff09;是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器&#xff0c;在相对应的软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设置系统的当前时间和日期。 RTC 模块和时钟配…

C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

【三剑客和正则表达式】

文章目录 学习目标一、什么是三剑客1.三剑客grep2.三剑客sed3.三剑客awk4.正则过滤例子15.正则过滤例子2 总结 学习目标 1.学会使用 grep 2.学会使用 sed 3.学会使用 awk 4.学会使用正则表达式一、什么是三剑客 正则三剑客&#xff1a;grep sed awk 1.三剑客grep # 擅长过滤…

AI整体架构设计5:CN+AI的三国杀

本文最后的图展示了气势磅礴的AICN&#xff08;云原生&#xff09;的技术栈&#xff0c;潜藏着无限的杀机。还在云原生的时候&#xff0c;研发和运维一直围绕着Devops进行两国杀。CNAI的时代&#xff0c;数据科学家加入了战局&#xff0c;彻底变成三国杀。边界的不断互相渗透&a…

【设计模式】JAVA Design Patterns——Combinator(功能模式)

&#x1f50d;目的 功能模式代表了一种以组合功能为中心的图书馆组织风格。 简单地说&#xff0c;有一些类型 T&#xff0c;一些用于构造类型 T 的“原始”值的函数&#xff0c;以及一些可以以各种方式组合类型 T 的值以构建更复杂的类型 T 值的“组合器” &#x1f50d;解释 真…

ubuntu20.04 10分钟搭建无延迟大疆无人机多线程流媒体服务器

1.使用效果 无人机画面 2.服务器视频端口 3.使用教程 3.1.下载ubuntu对应软件包&#xff1a;系统要求ubuntu16以上 3.2修改端口&#xff08;config.xml文件&#xff09; 3.3启动服务 目录下输入&#xff1a;终端启动&#xff1a;./smart_rtmpd 后台启动&#xff1a;nohup ./…