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

Java ==,equals()與hashcode()的使用

 更新時間:2023年05月22日 10:26:50   作者:按時交作業(yè)  
本文主要介紹了Java ==,equals()與hashcode()的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

==,equals()與hashcode()

"=="

在講解之前,我們是怎么接觸到==的,我們在作比較時經(jīng)常用到 ==, 這個符號常用作基本類的數(shù)據(jù)。

==運算符通常用于比較基本數(shù)據(jù)類型(如int、long、double等)和枚舉類型的值是否相等,而對于對象類型,==運算符用于比較它們的引用是否相等,即它們是否指向同一個對象。

思考一個問題,為什么我們一般不使用==來比較對象,如果兩個對象的引用相同,即它們指向同一個對象,那么使用==運算符比較它們的引用會返回true,因為它們確實指向同一個對象。在這種情況下,兩個對象的內(nèi)容自然是相同的,因為它們是同一個對象。

那為啥我們不直接使用==去比較對象, 而要麻煩的使用其它的辦法,

因為: 我們比較對象不是想看它的引用是否相同,而是里面的屬性是否相同

在這種情況下,使用==運算符比較兩個對象的引用并不能判斷它們的內(nèi)容是否相同,因為兩個不同的對象可能具有相同的屬性值,但它們的引用不同。因此,在比較對象是否相同時,應(yīng)該根據(jù)對象的語義來實現(xiàn)equals()方法,而不是使用==運算符。

public class Main {
    public static void main(String[] args) {
        int a = 5;
        int b = 5;
        int c = 6;
        System.out.println(a==b); // true
        System.out.println(a==c); // false
        Person p1 = new Person("hhh", 15);
        Person p2 = new Person("hhh", 15);
        // 屬性相同,但引用不同。按照常理應(yīng)該被認作是相同的。實際卻是不同的
        System.out.println(p1 == p2); // false
    }
}
class Person{
    String name;
    Integer age;
    Person(String name, Integer age){
        this.age = age;
        this.name = name;
    }
}

equals()方法

equals()方法是Object類中的方法,它僅僅是地址的比較,因此只能比較兩個類是否是同一個類,而不能比較屬性是否相同,因此,我們比較對象一般都會重寫equals()方法

public class Point {
    private int x;
    private int y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    // getters and setters
    @Override
    public boolean equals(Object obj) {
        return (this == obj);
    }
}

如果一個類的屬性包含基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,那么這些屬性值相同,但它們的引用地址也不一定相同。此時,必須重寫equals()方法,根據(jù)對象的語義來進行比較,才能得到正確的結(jié)果。

列表中的使用

在Java中,列表類(如List)通常用來存儲一組對象,當(dāng)我們需要在列表中查找某個對象時,通常需要調(diào)用列表的contains()方法或indexOf()方法。這些方法會使用對象的equals()方法來比較對象是否相等。

它是通過比較對象的屬性值從而去列表中查找。

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("A", "B", "C");
        // 下面的例子中即使對象的地址不同,但是屬性值相同,因此在列表中能查到
        System.out.println(list.contains(new String("C"))); // true
        System.out.println(list.indexOf(new String("C"))); // 2
    }
}

在hash結(jié)構(gòu)的表中使用

map是一種鍵值對的映射表,map使用一個很大的數(shù)組來存儲value,然后通過keyhash值來查找value的索引

map其實可以看作一個數(shù)組,keyhashcode()值可以作為數(shù)組的索引,然后根據(jù)索引去查找value。

那究竟在什么地方使用equals()呢?

當(dāng)我們輸入key的時候,map需要將傳入的key與當(dāng)前數(shù)組中存入的key相比較。

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put(new String("sss"),"hhh");
        map.put(new String("sss"), "aaa");
        // map里只有一個數(shù)據(jù),因為String重寫了equals方法,所以key屬性值一樣的會被覆蓋
        System.out.println(map.size());
        HashMap<Person, String> map1 = new HashMap<>();
        map1.put(new Person("xiao",15), "ok");
        map1.put(new Person("xiao",15), "hao");
        // map1里有兩個數(shù)據(jù),明明key是一樣的,卻沒有覆蓋
        System.out.println(map1.size());
    }
}
class Person{
    String name;
    int age;
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }
}
  • 添加重復(fù)的鍵值對:由于Map將不同的對象視為不同的鍵,如果我們使用相同類型的不同對象作為鍵,即使它們的屬性值相同,Map也會將它們視為不同的鍵,從而導(dǎo)致添加重復(fù)的鍵值對。
  • 無法查找鍵值對:由于Map將不同的對象視為不同的鍵,如果我們使用一個對象作為鍵添加了一個鍵值對,而后又使用另一個對象作為鍵查找該鍵值對,那么Map會認為這兩個對象是不同的鍵,因此無法找到對應(yīng)的鍵值對。

因此,我們需要正確重寫equals()方法。

hashcode()方法

HashMap為什么能通過key直接計算出value存儲的索引。相同的key對象(使用equals()判斷時返回true)必須要計算出相同的索引,否則,相同的key每次取出的value就不一定對。

map是通過hashcode()去尋找value數(shù)組索引的,所以還需要為對象覆寫hashcode()方法。

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put(new String("sss"),"hhh");
        map.put(new String("sss"), "aaa");
        // map里只有一個數(shù)據(jù),因為String重寫了equals方法和hashcode方法,所以key屬性值一樣的會被覆蓋
        System.out.println(map.size()); // 1
        HashMap<Person, String> map1 = new HashMap<>();
        Person p1 = new Person("xiao", 15);
        map1.put(p1, "ok");
        Person p2 = new Person("xiao", 15);
        map1.put(p2, "hao");
        // map現(xiàn)在也只有一個數(shù)據(jù)了,因為兩個相同屬性的對象被視作同一個
        System.out.println(map1.size()); // 1
    }
}
class Person{
    String name;
    int age;
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    // 覆寫equals方法
    @Override
    public boolean equals(Object o) {
        if (o instanceof Person p) {
            return this.name.equals(p.name) && this.age == p.age;
        }
        return false;
    }
    // 覆寫hashcode方法
    @Override
    public int hashCode() {
        int h = 0;
        h = 31 * h + name.hashCode();
        h = 31 * h + age;
        return h;
    }
}

mapput方法里是用到了hash值的,因此不正確重寫hash值而正確重寫equals方法是沒用的。

小節(jié)

比較基本數(shù)據(jù)類型或?qū)ο蟮刂酚?code>==, 比較對象地址使用Objectequals方法, 比較對象屬性值使用覆寫之后的equals().

對于list集合數(shù)據(jù)類型,本質(zhì)是數(shù)組,當(dāng)存儲對象數(shù)據(jù)類型的值時,重寫equals方法才能使用contains()等需要使用equals進行比較的方法。

對于hash table類型的數(shù)據(jù),必須覆寫equals與hashcode方法,才能正常工作。

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

相關(guān)文章

最新評論