美文网首页Java零基础入门
【JAVA 零基础入门系列】Day15 对象的比较

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

作者: 弗兰克的猫 | 来源:发表于2018-06-25 11:37 被阅读0次

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

      这一篇主要讲讲对象的比较,什么是对象的比较,我们知道两个数值类型只需要用 “==” 符号即可进行相等判断,但如果是两个 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 方法讲解完毕,很简单吧。之后还是会继续更新的,欢迎大家继续关注!

    相关文章

      网友评论

        本文标题:【JAVA 零基础入门系列】Day15 对象的比较

        本文链接:https://www.haomeiwen.com/subject/alzeyftx.html