关于接口中的一些常用实例以及比较方法的区别

news2024/11/28 20:38:44

文章目录

  • 💐文章导读
  • 🌴Object 类
    • toString() 获取对象信息
    • equals 对象比较方法
    • hashCode 获得对象的具体位置
  • 🌴接口使用实例
    • Comparable 接口
    • Comparator 接口

💐文章导读

在本篇文章中,详解了什么是Object类,一些Object类中的方法,以及两种接口的实现从而达到对象的比较,文章中的所讲的Object类中的方法以及两种比较的接口都应该熟悉的掌握!!!

🌴Object 类

object类是所有类的父类,在Java中是默认的,即使在定义类的时候没有显示的继承某个类,但是在Java中,每个类都会默认的继承Object类,所以,Object类的级别也就相当于所有类的祖宗!就像下面这种情况,实参在传对象时,形参的类型都可以定义成Object类型进行接受。

abstract class Experiment1{
    public abstract void action();
}
class Experiment2 extends Experiment1{
    public void action() {
        System.out.println("哈哈");
    }
}
public class Test {
    //定义形参为Object类型
    public static void method(Object obj) {
        //因为Object里没有action方法,所以转换成Experiment类型
        ((Experiment1)obj).action();
    }
    public static void main(String[] args) {
        Experiment2 experiment2 = new Experiment2();
        method(experiment2);
    }
}

在这里插入图片描述

可以看到并没有报错,所以证明了Object类就是所有类的父类,而在Object类中,又有许多可以经常用到的方法,下面我们看一下;按住Ctrl+点击Object

在这里插入图片描述

以上这些方法都是经常可以用到的,在这篇文章中会讲到getClass();equal();toString();clone();方法,请好好理解:

toString() 获取对象信息

toString()方法的作用是获取对象的信息,实例化一个对象后,使用toString()方法可以将字符串的信息在控制台打印出来,如下代码:

public class Test {
    private String name;
    private int age;

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

    public static void main(String[] args) {
        Test test =  new Test("李四",19);
        System.out.println(test);
    }
}

在这里插入图片描述

这是个什么东西,这并不是我实例化的对象内容啊,为什么会这样呢?下面看我解释:

首先我们先按住Ctrl+鼠标点击println这个方法,看看里面的是如何实现的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

所以刚刚最后打印出来的不是对象中的内容,那么要想打印出对象中的内容的话,需要在类中重写toString方法,因为:println方法最后是调用了Object类中的toString方法,所以才打印出了地址(这里可以理解成一个地址),因为所有的类都是Object类的子类,所以,通过动态绑定,利用在子类中重写父类的方法,最后调用子类中重写的方法,从而实现对象的打印:

在这里插入图片描述

equals 对象比较方法

public class Student {
    private String name;
    private int age;

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

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

    public static void main(String[] args) {
        //看起来一模一样对不对?
        Student student1 = new Student("李四",18);
        Student student2 = new Student("李四",18);
        //不能通过==进行判断
        //System.out.println(student1==student2);
        System.out.println(student1.equals(student2));
    }
}

在这里插入图片描述

这里不能通过==进行判断,因为两遍表达式都是基本类型的数据时,才能用 ==进行比较,而现在两边表达式都是引用类型的,所以不能比较,而这里换成equals进行比较的话也是false,这是为什么呢?那么,就要看一下这个equals的实现方式了,按住Ctrl+鼠标点击equals;

在这里插入图片描述

因为阿,在代码中,new了两次对象,虽然对象中的内容都是一样的,但他本质上是不一样的,它是在堆上开辟了两块空间,所以,在这里比较的是两块空间的地址,所以,得到的结果是false,如果要想对这两个对象进行比较,则要重写equals方法,下面重写:

    @Override
    public boolean equals(Object obj) {
        if(obj == null) {
            return false;
        }else if(this == obj) {
            return true;
        }else{
            //因为obj时object类型,里面没有name和age成员,所以要转换成Student
            return ((Student)obj).name.equals(((Student) obj).name) && ((Student) obj).age == ((Student) obj).age;
        }
    }

在这里插入图片描述

结论:如果要比较对象中的内容是否相同时,一定要重写equals方法

hashCode 获得对象的具体位置

现在回到刚刚调用的toString方法

在这里插入图片描述

在这里hashCode是计算出具体的对象位置,那么,请看下面代码:

  public static void main(String[] args) {
        //看起来一模一样对不对?
        Student student1 = new Student("李四", 18);
        Student student2 = new Student("李四", 18);
        System.out.println(student1.hashCode());
        System.out.println(student2.hashCode());
    }
}

在这里插入图片描述

算出了两串数字,这个数字是表示hashCode将地址以十六进制的形式打印出来,而这两个对象,因为内容是一样的,所以在逻辑上应该认为它们两个也应该存在一个地方,但是,本质上是不一样的,而如果想要在逻辑上把它们两个放在同一个地方,需要重写hashCode方法:

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

在这里插入图片描述

结论:hashCode方法时用来确定对象在内存中存储的位置是否相同

🌴接口使用实例

Comparable 接口

Comparable比较两个对象的大小,如果对象之间要想比较谁大谁小,需要实现Comparable这个接口,然后重写里面的comparto方法,指定两个对象的比较方式。具体代码实现:

public class Student implements Comparable<Student> {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //通过年龄进行比较
       @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
     public static void main(String[] args) {
        Student student1 = new Student("李四", 18);
        Student student2 = new Student("王五", 20);
        System.out.println(student1.compareTo(student2));
    }
}

下面根据名字进行比较

 @Override
 //只需要重写里面的comparto方法即可
    public int compareTo(Student o) {
           return this.name.compareTo(o.name);
    }

可以看到重写的comparto方法,与前面的requals不同,conparto方法是比较两个对象的大小,只要在comparto的重写方法中指定根据对象中的什么内容进行比较,就可以比较出两个对象的大小。所以返回值是int,而equals是比较两个对象是否相等,返回值是bolean类型的;

而在这里还需要注意一点问题需要知道:

在这里插入图片描述

下面再举个例:对数组中的内容进行排序

在这里插入图片描述

如果在没有重写comparto方法的前提下只用正常的Arrays.sort方法对数组进行排序是会报错的,因为排序的是一个对象,需要实现Comparable接口,重写comparto方法,指定根据什么进行排序,年龄或者姓名,下面请看代码:

   //需要实现Comparable接口
public class Student implements Comparable<Student> {
    private String name;
    private int age;

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

    @Override
    public String toString() {
        return "Test{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
           //根据名字进行排序
       @Override
    public int compareTo(Student o) {
        return this.name.compareTo(o.name);
    }
           //根据年龄进行排序
            //@Override
    //public int compareTo(Student o) {
       // return this.age-o.age;
   // }

   public static void main(String[] args) {
           Student[] arrays = new Student[]{new Student("zhangsan",14),new Student("lisi",11),new Student("wangwu",19)};
        Arrays.sort(arrays);
        System.out.println(Arrays.toString(arrays));
           }
}

在这里插入图片描述

Comparator 接口

Comparator接口也是实现两个对象进行比较,但是,这种比较方法比较独立,对类的侵入性不强,而上一种比较方法的缺点就是,当需要根据对象中不同的内容进行比较时,需要修改comparto方法中的内容,可能会对已经写好的代码造成影响,而这comparator这个接口则不会,下面通过代码讲解:

//根据年龄进行比较
class AgeCompar implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}
//根据姓名进行比较
class NameCompar implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
public class Student{
    String name;
     int age;

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

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

    public static void main(String[] args) {
        Student student1 = new Student("李四", 18);
        Student student2 = new Student("王五", 20);
        //只需要实例化两个比较器的对象即可
        //通过引用调用比较器里面的方法实现内容的比较
        AgeCompar ageCompar = new AgeCompar();
        NameCompar nameCompar = new NameCompar();
        System.out.println(ageCompar.compare(student1, student2));
        System.out.println(nameCompar.compare(student1,student2));
    }

在这里插入图片描述

以上代码就是**比较器比较,**优点是所有的比较方法都可以共存,想根据什么比较只需要写一个比较器就可以了,不需要对已经写好的代码进行修改。

作一下总结:

1、如果==两边是引用数据类型,则需要注意;这比较的是两个引用是否指向同一个对象

2、如果两个对象要进行比较是否相等,则要调用equals方法并且重写equals方法,指定根据对象中的什么内容进行比较,

3、如果是两个字符串吹进行比较是否相等,则要调用equals方法,不用重写;

4、如果比较两个对象的大小,则要实现Comparable接口,重写里面的comparto方法,指定根据什么进行比较

5,如果是字符串比较大小,只需调用comparto方法即可

点是所有的比较方法都可以共存,想根据什么比较只需要写一个比较器就可以了,不需要对已经写好的代码进行修改。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis中三级缓存的理解

文章目录 前言1. 环境搭建1.1 依赖引入1.2 mybatis-config.xml配置配置db.properties在mybatis-config.xml引入db.properties 1.3 实体类1.4 mappermapper接口mapper映射文件 1.5 测试 2.缓存2.1 一级缓存mybatis-config.xml 配置日志开启日志配置日志文件logback.xml测试相同m…

深度学习之搭建LSTM模型预测股价

大家好&#xff0c;我是带我去滑雪&#xff01; 本期利用Google股价数据集&#xff0c;该数据集中GOOG_Stock_Price_Train.csv为训练集&#xff0c;GOOG_Stock_Price_Test.csv为测试集&#xff0c;里面有开盘价、最高股价、最低股价、收盘价、调整后的收盘价、成交量&#xff0…

Flutter项目webview加载没有HTTPS证书的网页在Android和iOS设备上无法显示的解决方案

一、问题描述 Flutter项目使用谷歌官方webview库 webview_flutter&#xff0c;加载自签名证书、证书失效、无证书等HTTPS网页地址时&#xff0c;在Android或pc浏览器中提示证书失效&#xff0c;在iOS设备上为空白页&#xff0c;为了加载自签名证书的网页&#xff0c;需要饶过i…

AVR单片机ATemga328P中断原理的介绍

1、一AVR单片机中断原理的介绍 ATmega328P微控制器具有两个外部中断引脚&#xff0c;分别是INT0和INT1。 外部中断0&#xff08;INT0&#xff09;&#xff1a;它对应的引脚是PD2&#xff08;数字引脚2&#xff09;。INT0可以用于响应外部信号的边沿触发&#xff08;上升沿、下…

【服务器】使用Nodejs搭建HTTP web服务器

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 前言 1.安装Node.js环境 2.创建node.js服务 3. 访问node.js 服务 4.内网穿透 4.1 安装配置cpolar内网穿透 4.2 创建隧道映射本地端口 5.固定公网地址 [TOC] 转载自内网穿透…

Unity Addressables学习笔记(1)---创建远程服务器加载资源

例子1&#xff1a;加载一个图片 1.首先创建一个UI Image&#xff0c;空白图片,资源打包方式选择真是部署的 2.修改远程发布和加载配置 Bulid Path选择RemoteBuildPath Load Path我选择了custom,地址是http://localhost:8080/WebGL/ 遇坑1 :最开始我选择的Build Path 是 Loca…

windows安装mysql 5.7.41

前言 要学mysql&#xff0c;肯定得本地装上一个玩一玩啦&#xff0c;下面一起来安装mysql吧 一、下载 https://downloads.mysql.com/archives/community/ 顺便说一下&#xff0c;下载按钮下方有个md5&#xff0c;可以验证下文件是否被篡改&#xff0c;理论上官网下载的应该问…

初识结构体

目录 结构体的声明 结构体的基础知识 结构体的声明 结构体成员的类型 结构体变量的定义和初始化 定义 初始化 结构体成员的访问 结构体变量访问成员 结构体指针访问指向变量的成员 结构体传参 传地址 传结构体 结论 结构体的声明 结构体的基础知识 数组&#xff…

【ChatGPT】IOS如何下载注册使用ChatGPT的APP(教学)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、…

iptables 防火墙

iptables概述 Linux系统的防火墙&#xff1a;ip信息过滤系统&#xff0c;它实际上由两个组件netfilter和iptables组成。 主要工作在网络层&#xff0c;针对IP数据包。体现在对包内的IP地址、端口、协议等信息的处理上 netfilter / iptables关系&#xff1a; netfilter:属于…

Electron中如何创建模态窗口?

目录 前言一、模态窗口1.Web页面模态框2.Electron中的模态窗口3.区分父子窗口与模态窗口 二、实际案例使用总结 前言 模态框是一种常用的交互元素&#xff0c;无论是在 Web 网站、桌面应用还是移动 APP 中&#xff0c;都有其应用场景。模态框指的是一种弹出窗口&#xff0c;它…

【TES714】JFM7K325T(复旦微FPGA)+HI3531DV200(华为海思)的综合视频处理平台设计原理图及调试经验

板卡概述 TES714是自主研制的一款5路HD-SDI视频采集图像处理平台&#xff0c;该平台采用上海复旦微的高性能Kintex系列FPGA加上华为海思的高性能视频处理器HI3531DV200来实现。 华为海思的HI3531DV200是一款集成了ARM A53四核处理器性能强大的神经网络引擎&#xff0c;支持多种…

【运维知识进阶篇】集群架构-Nginx动静分离详解

我们先前将静态资源放到NFS&#xff0c;动态资源放到MySQL&#xff0c;一是为了提高我们Web服务器性能&#xff0c;减轻它的压力&#xff0c;另一面如果Web宕机了&#xff0c;我们的静态和动态资源还可以访问到。但是之前方式不管是静态还是动态文件&#xff0c;都是走的代码文…

ssl vpn 与 ipsec vpn 区别

VPN 安全协议有两种主要类型&#xff0c;IPsec 和 SSL&#xff0c;了解它们之间的区别对于确保客户的安全至关重要。在本文中&#xff0c;我们将解释IPsec 和 SSL VPN 协议之间的区别&#xff0c;以及如何选择合适的协议来满足客户的需求。了解更多SSL技术最新信息&#xff0c;…

Linux_证书_Openssl实现对称加密、非对称加密、CA颁布证书

文章目录 OpenSSLopenssl实现对称加密openssl实现非对称加密生成密钥对非对称加密数字签名小结 根据CA颁布证书生成ca私钥和ca证书根据ca生成证书 尾声 OpenSSL 常用证书生成工具包括三个&#xff1a;ssh-keygen、cfssl、openssl。这里介绍 OpenSSL , OpenSSL 是一个开源项目&…

【Python从入门到进阶】20、HTML页面结构的介绍

接上篇《19、Python异常处理》 上一篇我们学习了Python中有关异常&#xff08;捕获异常、处理异常等&#xff09;的知识。从本篇开始&#xff0c;我们进入Python的实战教程&#xff0c;学习爬虫的相关技术&#xff0c;本篇主要讲解要爬取的HTML页面的结构。 一、一个场景 假设…

Godot引擎 4.0 文档 - 入门介绍 - Godot 编辑器

本文为Google Translate英译中结果&#xff0c;DrGraph在此基础上加了一些校正。英文原版页面&#xff1a; First look at Godots editor — Godot Engine (stable) documentation in English Godot的编辑器 本页将为您简要介绍 Godot 的界面。我们将查看不同的主屏幕和停靠栏…

C语言:字符函数和字符串函数详解及部分函数的模拟实现(前篇)

文章目录 求字符串长度strlenstrlen函数的模拟实现: 长度不受限制的字符串函数strcpystrcatstrcmp总结 长度受限制的字符串函数介绍strncpystrncatstrncmp 前言&#xff1a; C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串…

【LeetCode】382. 链表随机节点

382. 链表随机节点&#xff08;中等&#xff09; 方法一 思路 定义两个链表&#xff0c;一个origin&#xff0c;用于每次调用 getRandom() 时进行初始化&#xff0c;一个 l 用于每次调用 getRandom() 时进行遍历&#xff0c;找到随机选定的元素。首先在 Solution() 的时候&am…

SpringBoot原理——起步依赖与自动装配

文章目录 SpringBoot原理一、起步依赖二、自动配置2.1 概述2.2 工具类准备工作2.2.2 HeaderConfig2.2.3 HeaderGenerator2.2.4 HeaderParser2.2.5 MyImportSelector2.2.6 TokenParser2.2.7 pom.xml文件 2.3 自动配置原理2.3.1 引入工具类2.3.2 案例 &#xff1a; 访问第三方Bea…