逻辑运算符(==, !=)比较的是啥?equals()比较的是啥?

逻辑运算符(==, !=)比较的是啥?equals()比较的是啥

文章目录

关系运算符

关系运算符会通过产生一个布尔(boolean)结果来表示操作数之间的关系。如果关系为真,则结果为 true,如果关系为假,则结果为 false。关系运算符包括小于 <,大于 >,小于或等于 <=,大于或等于 >=,等于 == 和不等于 !=。

== 和 != 可用于所有基本类型,但其他运算符不能用于基本类型 boolean,因为布尔值只能表示 true 或 false,所以比较它们之间的 “大于” 或 “小于” 没有意义。

== 和 != 测试对象等价

== 和 != 用于比较对象时,比较的是对象引用,即对象在堆中的地址,地址一样则相同。但有个特殊情况

特殊情况

基本数据类型int 的包装类型 Integer 有些特殊。

关系运算符 == 和 != 同样适用于所有对象之间的比较运算,但它们比较的内容却经常困扰 Java 的初学者。下面是代码示例:

// operators/Equivalence.java
public class Equivalence {
    public static void main(String[] args) {
        Integer n1 = 47;
        Integer n2 = 47;
        System.out.println(n1 == n2);
        System.out.println(n1 != n2);
    }
}

输出结果:
true
false

表达式 System.out.println(n1 == n2) 将会输出比较的结果。因为两个 Integer对象相同,所以先输出 true,再输出 false。但是,尽管对象的内容一样,对象的引用却不一样。== 和 != 比较的是对象引用,所以输出实际上应该是先输出 false,再输出true。

但它的特殊点就 在于 Integer 内部维护着一个 IntegerCache 的缓存,默认缓存范围是 [-128, 127],这个缓存可以被称为整数缓冲区,假设我们通过Integer创建数据,如果这个数据的范围在-128~127之间,就是直接引用数组cache 中已有的数据。所以 [-128, 127] 之间的 值 用 == 和 != 比较也能能到正确的结果,但是不推荐用关系运算符比较,具体见 JDK 中的 Integer 类源码。

(注:如果你把 47 改成 128,那么打印的结果就是先输出 false,再输出true,因为脱离了整数缓冲区的范围,比较的就是对象引用了

equals() 方法

equals() 的默认行为也是比较 对象的引用 而非具体内容,只不过一般我们都会重写equals()方法,让其比较内容。

那么怎么比较两个对象的内容是否相同呢? 你必须使用所有对象(不包括基本类型)中都存在的 equals() 方法,下面是如何使用 equals() 方法的示例:

// operators/EqualsMethod.java
public class EqualsMethod {
    public static void main(String[] args) {
        Integer n1 = 47;
        Integer n2 = 47;
        System.out.println(n1.equals(n2));
    }
}

输出结果: true

注意:

上例的结果看起来是我们所期望的。但其实事情并非那么简单。下面我们来创建自己的类:

// operators/EqualsMethod2.java
// 默认的 equals() 方法没有比较内容
class Value {
	int i;
}
public class EqualsMethod2 {
    public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
            System.out.println(v1.equals(v2));
    }
}

输出结果: false

上例的结果再次令人困惑:结果是 false。

原因:equals() 的默认行为是比较对象的引用而非具体内容。

因此,除非你在新类中覆写 equals() 方法,否则我们将获取不到想要的结果。不幸的是,在学习 复用(Reuse)章节后我们才能接触到 “覆写”(Override),并且直到 附录: 集合主题,才能知道定义 equals() 方法的正确方式,但是现在明白 equals() 行为方式也可能为你节省一些时间。

大多数 Java 库类通过覆写 equals() 方法比较对象的内容而不是其引用。

String类中的equals()方法重写

我们来看一下String类是怎么复写Object.java中的equals()方法的:

 private final char value[];
/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

我们自己创建一个对象的equals()方法重写

package com.wlw.chapter8_collection;

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

    @Override
    public boolean equals(Object o) {
        //1.判断是否为同一对象
        if(this == o){
            return true;
        }
        //2.判断是否为空
        if(o == null){
            return  false;
        }
        //3.判断是否为Student类型
        if(o instanceof Student){
            //4.类型转换
            Student s = (Student) o;
            //5.比较内容
            if(this.name.equals(s.getName()) && this.age == s.getAge()){
                return  true;
            }
        }
        // 不满足返回false
        return false;
    }
}
上一篇:1.4 ==与equals


下一篇:[java必知必会] “==“和equals方法究竟有什么区别?