欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中equals()方法實例詳解

 更新時間:2021年12月24日 10:23:47   作者:changshuchao  
equals方法是java.lang.Object類的方法,下面這篇文章主要給大家介紹了關(guān)于Java中equals()方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

equals()在哪里

首先我們知道Java中Object類是所有類的父類,它里面定義了equals()方法:

    public boolean equals(Object obj) {
        return (this == obj);
    }

可以看到是使用= =來進行比較的,那么= =是什么意思呢?其實是比較兩個對象的的內(nèi)存地址。(這里順便提一下,可以去了解一下Java的堆棧。)

=》若object1.equals(object2)為true,則表示equals1和equals2實際上是引用同一個對象。

Java中重寫的equals()

這里我們看一下java的一些自帶的包裝類怎么重寫equals()的:

String.java

    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;
    }

我們可以非常清晰的看到String的equals()方法是進行內(nèi)容比較,而不是單純的引用比較。

Integer.java

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

其他的就不一一舉例了。

在Java中比較的推薦方法

所以我們一般比較基本數(shù)據(jù)類型的時候,使用"==",例如 int i = 0; if (i == 1){…},比較兩個Integer包裝類類型的時候就可以使用equals(),因為Java已經(jīng)重寫了equals()方法了。另外給出幾點建議,在java中進行比較,我們需要根據(jù)比較的類型來選擇合適的比較方式:

  1. 對象域,使用equals方法 。
  2. 類型安全的枚舉,使用equals或== 。
  3. 可能為null的對象域 : 使用==null 和 equals 。
  4. 數(shù)組域 : 使用 Arrays.equals 。
  5. 除float和double外的原始數(shù)據(jù)類型(int,byte等) : 使用 == 。
  6. float類型: 使用Float.foatToIntBits轉(zhuǎn)換成int類型,然后使用==。
  7. double類型: 使用Double.doubleToLongBit轉(zhuǎn)換成long類型,然后使用==。

其中6,7參考java中的對應(yīng)的包裝類實現(xiàn):

public boolean equals(Object obj) {
    return (obj instanceof Float)
           && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
    }
}

為什么要在我們自己的類中重寫equals()

但是有時候我們不滿足于使用基本數(shù)據(jù)類型和Java實現(xiàn)的一些繼承自O(shè)bject的哪些類,比如我們實現(xiàn)一個Person類,它是繼承自O(shè)bject類的,所以它的equals()方法默認(rèn)使用的是文章開頭提到的哪個equals()方法,當(dāng)我們使用equals()進行比較的時候,比較內(nèi)存地址,那么有可能出現(xiàn)兩個Person對象的參數(shù)都相同(比如年齡,身份證號等,在我們的實際認(rèn)知中認(rèn)為這兩個人就是一個人,應(yīng)該返回true),但是由于他們的內(nèi)存地址是不一樣的,所以equals()方法會返回false。

那么我們就需要去重寫equals()方法。

重寫equals()的規(guī)范

需要注意的是,在Java規(guī)范中,它對equals()方法的使用必須要遵循如下幾個規(guī)則:

  1. 自反性:對于任何非空引用值 x,x.equals(x) 都應(yīng)返回 true。
  2. 對稱性:對于任何非空引用值 x 和 y,當(dāng)且僅當(dāng)y.equals(x) 返回 true 時,x.equals(y) 才應(yīng)返回 true。
  3. 傳遞性:對于任何非空引用值 x、y 和z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 應(yīng)返回 true。
  4. 一致性:對于任何非空引用值 x 和 y,多次調(diào)用 x.equals(y) 始終返回 true 或始終返回4、一致性:對于任何非空引用值 x 和 y,多次調(diào)用 x.equals(y) 始終返回 true 或始終返回false,前提是對象上 equals 比較中所用的信息沒有被修改
  5. 對于任何非空引用值 x,x.equals(null) 都應(yīng)返回false。

重寫equals()可能的誤區(qū)

查看下述代碼:

public class TestEquals {
    public static void main(String[] args) {
        Employee employee = new Employee("mily",1);
        Employee employee2 = new Employee("mily",2);
        Person p1 = new Person("mily");
        
        System.out.println(p1.equals(employee));
        System.out.println(p1.equals(employee2));
        System.out.println(employee.equals(employee2));
    }
}

class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    @Override
    public boolean equals(Object obj) {

        if (obj instanceof Person) {
            Person person = (Person) obj;
            if (person.getName() == null | name == null) {
                return false;
            } else {
                return name.equalsIgnoreCase(person.getName());
            }
        }

        return false;
    }
}

class Employee extends Person {

    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(String name, int id) {
        super(name);
        this.id = id;
    }

    @Override
    public boolean equals(Object obj) {

        if (obj instanceof Employee) {
            Employee employee = (Employee) obj;
            return super.equals(obj) && employee.getId() == id;
        }

        return false;
    }
}

輸出:

true

true

false

上述代碼中,我定義了一個Person類,有一個屬性name;還定義了一個Employee類,它是Person的子類,多出一個id的屬性;在測試代碼中“new”出了三個對象:

  1. name為mily,id為1的一個職員 —— employee
  2. name為mily,id為2的職員 —— employee2
  3. name為mily的一個普通人 —— p1

在大家的認(rèn)知下,應(yīng)該是三者都不是“equal”的,但是在執(zhí)行 p1.equals(employee)時返回的是true,仔細(xì)看了代碼之后你就會發(fā)現(xiàn)問題所在,代碼把employee當(dāng)成一個Person對象去執(zhí)行equals方法了,比較了name發(fā)現(xiàn)一樣,就認(rèn)為是“equal”了,這是一種很常見的誤區(qū)。

一般的equals()寫法

下面給出一個完美的 equals 方法的建議:

1、顯示參數(shù)命名為 otherObject,稍后會將它轉(zhuǎn)換成另一個叫做 other 的變量。

2、判斷比較的兩個對象引用是否相等,如果引用相等那么表示是同一個對象,那么當(dāng)然相等

3、如果 otherObject 為 null,直接返回false,表示不相等

4、比較 this 和 otherObject 是否是同一個類:如果 equals 的語義在每個子類中有所改變,就使用 getClass 檢測;如果所有的子類都有統(tǒng)一的定義,那么使用 instanceof 檢測

5、將 otherObject 轉(zhuǎn)換成對應(yīng)的類類型變量

6、最后對對象的屬性進行比較。使用 == 比較基本類型,使用 equals 比較對象。如果都相等則返回true,否則返回false。注意如果是在子類中定義equals,則要包含 super.equals(other)

按照上述的equals()規(guī)范,我的實現(xiàn)如下:

public class TestEquals2 {
    public static void main(String[] args) {
        Employee employee = new Employee("mily",1);
        Employee employee2 = new Employee("mily",1);
        Person p1 = new Person("mily");

        System.out.println(p1.equals(employee));
        System.out.println(p1.equals(employee2));
        System.out.println(employee.equals(employee2));

        Employee employee3 = new Employee(null,1);
        Employee employee4 = new Employee(null,1);
        Person p2 = new Person(null);
        System.out.println(p2.equals(employee3));
        System.out.println(p2.equals(employee4));
        System.out.println(employee3.equals(employee4));
    }
}

class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }

        if(obj == null || getClass() != obj.getClass()){
            return false;
        }

        Person person = (Person) obj;
        if(person.getName() == null | name == null) {
            return false;
        } else {
            return name.equalsIgnoreCase(person.getName());
        }

    }
}

class Employee extends Person {

    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(String name, int id) {
        super(name);
        this.id = id;
    }

    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }

        if(obj == null || getClass() != obj.getClass()){
            return false;
        }

        Employee employee = (Employee) obj;
        if(employee.getName() == null | getName() == null) {
            return false;
        }else {
            return getName().equalsIgnoreCase(employee.getName()) && employee.getId() == id;
        }

    }
}

結(jié)果:

false

false

true

false

false

false

附:java中equals()方法的正確使用

在Java中比較兩個字符串是否相等,想必只要不是初學(xué)者都知道用equals()方法來進行比較,但是實際上很多時候都用錯了。

就我自己開發(fā)而言,加入比較一個String s的內(nèi)容是否是"aaa"時,往往會寫成如下代碼:

if(s.equals("aaa")){
    ...
}

乍一看沒什么問題,直到我裝了Alibaba Coding Guidelines 這個插件,一檢查,就告訴我這樣不對了。

為什么呢?因為很多情況下,并不能保證字符串s是不是為null,即直接這么判斷,很容易產(chǎn)生空指針異常的錯誤,因此正確的使用方法應(yīng)該是:

"aaa".equals(s);

總結(jié)

到此這篇關(guān)于Java中equals()方法的文章就介紹到這了,更多相關(guān)Java?equals()方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論