【JAVA零基础入门系列】Day15 对象的比较

news/2024/7/7 20:34:21

  【JAVA零基础入门系列】(已完结)导航目录

  • Day1 开发环境搭建
  • Day2 Java集成开发环境IDEA
  • Day3 Java基本数据类型
  • Day4 变量与常量
  • Day5 Java中的运算符
  • Day6 Java字符串
  • Day7 Java输入与输出
  • Day8 Java的控制流程
  • Day9 Java中的那个大数值
  • Day10 Java中的数组
  • Day11 Java中的类和对象
  • Day12 Java类的简单应用
  • Day13 Java类的继承与多态
  • Day14 Java对象的克隆
  • Day15 对象的比较

  最近一直有事,博客也停笔了一段时间,十分抱歉。

  这一篇主要讲讲对象的比较,什么是对象的比较,我们知道两个数值类型只需要用“==”符号即可进行相等判断,但如果是两个Goods对象呢?如何进行比较?这时候,我们的equals方法就派上用场了。equals方法是类的祖先Object类的另一个protected方法,既然是protected方法(能被同一个包里的所有类所访问, 能被该类的子类所访问,子类可以和父类不在一个包中),子类是可以直接访问的,但如果没有覆盖该方法,那么使用的只是Object的原始比较方法,return(this==obj) ,仅仅比较两个对象的地址是否一致。

  对于String类型,已经设计好了equals方法,所以我们只需要拿来用就可以了,如果是我们自定义的类,那就得重写该方法来进行覆盖,下面还是用Goods类来举一个小栗子:

public class Goods {
    private String title;
    private double price;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    //构造器
    public Goods(String title, double price) {
        this.title = title;
        this.price = price;
    }
}

  这是简化版的Goods类,有两个私有成员变量以及它们的设置器,访问器,还有一个构造器,下面我们来重写父类的equals方法,判断两个Goods是否相等,逻辑上,我们只需要两者标题和价格一致即可认为两个商品是相等的(当然可以根据实际情况进行调整),下面我们来设计一下equals方法:

/**
 * @author Frank
 * @create 2017/11/20
 * @description 被测试类,测试equals方法
 */
public class Goods {
    private String title;
    private double price;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    //构造器
    public Goods(String title, double price) {
        this.title = title;
        this.price = price;
    }

    //覆盖equals方法
    @Override
    public boolean equals(Object obj) {
        Goods tmp = (Goods) obj;
        if (price == tmp.getPrice() && title.equals(tmp.getTitle())){
            return true;
        }else {
            return false;
        }
    }
}

  这里我们覆盖了父类的equals方法,在equals方法中将obj强制类型转换为Goods类,再比较两者价格和标题是否相等,只要都相等,则返回true,否则返回false,这也符合我们的需求,下面测试一下:

/**
 * @author Frank
 * @create 2017/11/20
 * @description 测试类,用于测试equals方法
 */
public class Test {
    public static void main(String[] args) {
        Goods a = new Goods("Java",100);
        Goods b = new Goods("C++",100);
        Goods c = new Goods("Java",100);
        System.out.println(a.equals(b));
        System.out.println(a.equals(c));
    }
}

  输出结果为:false  ture

  这样我们就简单的实现了equals方法,但是,这个equals方法并不完美,首先,由于我们传入的是Object对象,所以并不知道它原本的类型是否为Goods类型,如果不是Goods类型,当然不能拿来比较,于是我们得先进行一下类型判断:

@Override
    public boolean equals(Object obj) {//类型判断
        if (obj.getClass() != this.getClass()){
            return false;
        }else {
            Goods tmp = (Goods) obj;
            if (price == tmp.getPrice() && title.equals(tmp.getTitle())){
                return true;
            }else {
                return false;
            }
        }
    }

 

  仍旧不完美,如果比较的对象就是自身或者两者指向同一个对象的话,直接返回true即可:

@Override
    public boolean equals(Object obj) {
        //先检测是否为自比较
        if ( this == obj || obj == null){
            return true;
        }
        //类型判断
        if (obj.getClass() != this.getClass()){
            return false;
        }else {
            Goods tmp = (Goods) obj;
            if (price == tmp.getPrice() && title.equals(tmp.getTitle())){
                return true;
            }else {
                return false;
            }
        }
    }

  现在就好很多了,那么此时我们调用equals方法跟使用”==“比较符号有什么区别呢,来看一个栗子:

public class Test {
    public static void main(String[] args) {
        Goods a = new Goods("Java",100);
        Goods b = new Goods("C++",100);
        Goods c = new Goods("Java",100);
        Goods d = a;
        System.out.println(a.equals(b));
        System.out.println(a.equals(c));
        System.out.println(a.equals(d));
        System.out.println(a==b);
        System.out.println(a==c);
        System.out.println(a==d);
    }
}

  输出如下:

false
true
true
false
false
true

  对于前三个输出应该没什么问题,主要看后三个,这里用相等比较符时,判断的仅仅是两个变量存储的内容是否一致,由于a、b、c、d均为引用类型,所以比较的仅仅是它们是否指向相同的对象,这里只有a跟d指向的是相同的对象,c虽然title和price都与a相同,但是跟a是两个完全不同的对象,因此没有返回的是false。

  另外,有人也许会问,做类型判断的时候,为什么不用instanceof或者isInstance方法,这里简单说明一下原因。instance判断的是a对象是否和b对象属于同一个类,或者有同一个父类,或者实现了同一个接口。isinstance方法则判断两种类型是否可以进行强转。

  由于这个小栗子并没有相关上下文,所以还是直接用getClass方法进行判断比较稳妥,当然,以后可以根据具体实际情况进行修改。

  至此,equals方法讲解完毕,很简单吧。之后还是会继续更新的,欢迎大家继续关注!

 

真正重要的东西,用眼睛是看不见的。

http://www.niftyadmin.cn/n/2748055.html

相关文章

php7 refcount,PHP 7下变量的zval的refcount为何是2?

代码如下:$a "hello world";xdebug_debug_zval(a);然后在PHP7下运行:a: (refcount2, is_ref0)hello world在PHP5.5下运行:a: (refcount1, is_ref0)hello worldPHP 7的版本信息如下:PHP 7.1.5 (cli) (built: May 9 2017…

php分页高亮,php分页函数

/*** 分页函数* by hkshadow* 2011-04-07* Enter description here ...* param 结果总条数count(); $num* param 每页条数 $perpage* param 当前页 $curpage* param 分页地址$url index.php? . $para; $mpurl* param 数字分页数量 $page* $multipage ListMulti ( $max, $tpp…

Nginx的https配置记录以及http强制跳转到https的方法梳理

为什么80%的码农都做不了架构师?>>> Nginx的https配置记录以及http强制跳转到https的方法梳理 一、Nginx安装(略) 安装的时候需要注意加上 --with-httpsslmodule,因为httpsslmodule不属于Nginx的基本模块。 Nginx安装…

数据库设计系列9--将ER模型映射为表

在前面的步骤中,我们创建了数据库的ER模型,ER模型属于概念级别的模型,需要映射为表才能被计算机存储。本章节的目标就是从ER模型中创建表,并检查这些表的结构。这组表应该代表逻辑数据库模型中的实体,关系,…

window环境进行服务器渲染

npm install babel-cli --save配置package,jsonScriptcross-env能跨平台地设置及使用环境变量 大多数情况下,在windows平台下使用类似于: NODE_ENVproduction的命令行指令会卡住,windows平台与POSIX在使用命令行时有许多区别(例如在POSIX&…

Jersey基础知识学习过程记录(一)

为什么80%的码农都做不了架构师?>>> 项目需要,做一个RESTful架构的web服务,结构为intellijmavenjerseytomact, 整体是混合着讲解的. 创建工程需要的资源如下:IntelliJ TomcatMavenJDK首先在intellij新建工程,选择java…

python代码存取数据,几行代码轻松搞定python的sqlite3的存取

很简单:存数据:1、加载sqlite3驱动(只需一行代码)2、用驱动执行查询语句(只需一行代码)取数据:1、加载sqlite3驱动(只需一行代码)2、用驱动执行查询语句(只需一行代码)乍一看,sqlite存取数据方式似乎都一样,实际上&…

Confluence 6 启用嵌套用户组

一些目录服务器能够允许你在一个组中定义另外一个组。在这种结构下的用户组称为用户组嵌套。嵌套组的配置能够让子用户组继承上级用户组的权限,使系统的权限配置变得简单。这个页面描述了 Confluence 是如何在一个或者多个用户服务器上如何处理嵌套用户组。你可以为…