最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中的HashSet與 == 和 equals的區(qū)別示例解析

 更新時(shí)間:2025年02月04日 10:10:34   作者:何人陪我共長生  
HashSet是Java中基于哈希表實(shí)現(xiàn)的集合類,特點(diǎn)包括:元素唯一、無序和可包含null,本文給大家介紹java中的HashSet與 == 和 equals的區(qū)別,感興趣的朋友一起看看吧

什么是HashSet

在 Java 中,HashSet 是一個(gè)基于哈希表實(shí)現(xiàn)的集合類,它實(shí)現(xiàn)了 Set 接口
HashSet 的主要特點(diǎn)是:1,2

HashSet 的主要特點(diǎn)是

1,集合中的數(shù)據(jù)不能夠重復(fù)
2,存儲的數(shù)據(jù)是無序的(元素的存儲順序與插入順序無關(guān))
3,允許 null 值: 可以存儲一個(gè) null 元素(感覺這個(gè)不算)

HashSet 的常用方法

boolean add(e)向集合中添加元素。如果元素已存在,則返回 false。
boolean remove(Object o)從集合中移除指定元素。如果元素存在并成功移除,則返回 true。
boolean contains(Object o)檢查集合中是否包含指定元素。如果存在,則返回 true。
int size() 返回集合中元素的數(shù)量。
boolean isEmpty()檢查集合是否為空。如果為空,則返回 true。
void clear()清空集合中的所有元素。
Iterator iterator() 返回一個(gè)迭代器,用于遍歷集合中的元素。
Object[] toArray() 將集合轉(zhuǎn)換為數(shù)組。

hasSet存儲為啥是無序的

hasSet 存儲為啥數(shù)據(jù)不能夠重復(fù)

hash存儲是冪等性算法
也就是說:你給我一個(gè)A,計(jì)算出來的是2。
下次你再給一個(gè)A,計(jì)算出來的仍然是2。
這樣的話,就會造成一個(gè)問題。
這個(gè)2要不要存儲呢?
hasSet會丟棄第2個(gè)相同的值,因此存儲的數(shù)據(jù)是不能夠重復(fù)的。

存儲數(shù)據(jù)是無序的

package part;
// HashSet在util這個(gè)包中,需要我們引入
import java.util.HashSet;
public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("趙6");
        // 輸出的來是: [趙6, 李四, 張三] 說明存儲數(shù)據(jù)是無序的
        System.out.println(setObject);
    }
}

存儲的數(shù)據(jù)是不會重復(fù)的

public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("張三");
        // 輸出的來是:
        System.out.println(setObject);
    }
}

HashSet如何修改數(shù)據(jù)

HashSet無法直接修改數(shù)據(jù)。
我們需要先把某一條要修改的數(shù)據(jù)刪除掉。在新增我們想要的數(shù)據(jù)

package part;
// HashSet在util這個(gè)包中,需要我們引入
import java.util.HashSet;
public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        // 把張三更改為張3,我們先刪除然后再新增
        setObject.remove("張三");
        setObject.add("張3");
        // 輸出: [李四, 張3]
        System.out.println(setObject);
    }
}

增強(qiáng) for循環(huán)(也稱為 for-each 循環(huán)) 來遍歷數(shù)據(jù)

package part;
// HashSet在util這個(gè)包中,需要我們引入
import java.util.HashSet;
public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 我們通過特殊for循環(huán)來遍歷數(shù)據(jù)
        for (Object o : setObject) {
            System.out.println(o);
        }
    }
}

增強(qiáng) for循環(huán)的語法

for (元素類型 變量名 : 數(shù)組或集合) {
    // 循環(huán)體 
    // ps: 變量名是循環(huán)中的每一項(xiàng)
}

HashSet.add新增元素(如果元素已存在,則返回 false)

package part;
// HashSet在util這個(gè)包中,需要我們引入
import java.util.HashSet;
public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 輸出的是 [李四, 張三, 王五]
        System.out.println(setObject);
    }
}

HashSet.addAll 將一個(gè)集合中的所有元素添加到另一個(gè)集合中

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        ArrayList<Integer> listObject = new ArrayList();
        listObject.add(1);
        listObject.add(2);
        LinkedList linkedListObject = new LinkedList();
        linkedListObject.add("張三");
        // 添加一個(gè)ArrayList集合對象
        setObject.addAll(listObject);
        // 添加一個(gè)LinkedList集合對象
        setObject.addAll(linkedListObject);
        // 輸出的是: [1, 2, 張三]
        System.out.println("setObject:" + setObject);
    }
}

HashSet.toArray 將HashSet轉(zhuǎn)化為數(shù)組

public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 將 HashSet 轉(zhuǎn)換為數(shù)組
        Object obj = setObject.toArray();
        System.out.println(obj);
    }
}

HashSet.size() 獲取HashSet 的長度

public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 獲取HashSet 的長度
        int len = setObject.size();
        System.out.println(len);
    }
}

HashSet.clone 克隆

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 克隆HashSet,相當(dāng)于復(fù)制了一份。但是我們需要使用Object來聲明
        Object newSet = setObject.clone();
    }
}

克隆 HashSet 可以不用Object來聲明嗎?

克隆 HashSet 可以不用 Object 來聲明嗎? 可以的。
那為啥克隆需要使用 Object來聲明呢?
因?yàn)椋篶lone() 方法的返回類型是 Object。所以我們需要使用Object來聲明。
我們可以使用強(qiáng)制轉(zhuǎn)化來處理就行

public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 克隆HashSet,相當(dāng)于復(fù)制了一份。我們可以使用強(qiáng)制轉(zhuǎn)化來解決這個(gè)問題的
        HashSet newSet =(HashSet) setObject.clone();
    }
}

HashSet.remove(被移除的對象)

要從 HashSet 中移除的對象。如果 HashSet 包含該對象,則會被移除。
返回值是一個(gè)布爾值
如果 HashSet 中包含指定的對象并且成功移除,則返回 true。
如果 HashSet 中不包含該對象,則返回 false。

public class Java01 {
    public static void main(String[] args) {
        HashSet setObject = new HashSet();
        setObject.add("張三");
        setObject.add("李四");
        setObject.add("王五");
        // 移除李四
        Boolean delStatus = setObject.remove("李四");
        // 輸出的是true
        System.out.println(delStatus);
    }
}

ArrayList.remove根據(jù)傳參不同,返回的類型不同

ArrayList arrList = new ArrayList();
arrList.add("嘿嘿01");
// 傳參的是數(shù)字,返回的是被刪除的數(shù)據(jù)
Object oldValue = arrList.remove(0);
public class Java01 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("A");
        // 傳參字符串,返回來的是布爾
        Boolean flag = list.remove("A");
        System.out.println(flag);
    }
}

HashSet存儲了相同的數(shù)據(jù)

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
public class Java01 {
    public static void main(String[] args) {
       HashSet setList = new HashSet();
       User u1 = new User();
       User u2 = new User();
        u1.id = "2025_01_30";
        u1.name = "張三";
        u2.id = "2025_01_30";
        u2.name = "張三";
        setList.add(u1);
        setList.add(u2);
        // 大家認(rèn)為會輸出什么呢?
        // 輸出的 [User [id=2025_01_30, name=張三], User [id=2025_01_30, name=張三]]
        System.out.println(setList);
    }
}
class User{
    String id;
    String name;
    // ctrl + o 就可以啦 現(xiàn)在我重寫了 toString
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}

不是說:HashSet中的數(shù)據(jù)不能重復(fù)嗎?
為啥會重復(fù)呢?
因?yàn)?這2個(gè)對象在內(nèi)存中是不同的地址哈~。
所以HashSet會認(rèn)為是不同的值。
內(nèi)存中是不同的地址我們一般認(rèn)為是 hashCode不同(這種說法不準(zhǔn)確,但是方便我們理解)
ps: hashCode類似與內(nèi)存中的地址

解釋為啥存儲了相同的數(shù)據(jù)

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
public class Java01 {
    public static void main(String[] args) {
       HashSet setList = new HashSet();
       User u1 = new User();
       User u2 = new User();
        u1.id = "2025_01_30";
        u1.name = "張三";
        u2.id = "2025_01_30";
        u2.name = "張三";
        setList.add(u1);
        setList.add(u2);
        // hashCode 我們可以理解為內(nèi)存中的地址(這種說法不準(zhǔn)確,但是方便我們理解)
        System.out.println(u1.hashCode()); // 685325104
        System.out.println(u2.hashCode()); // 460141958
        // 我們發(fā)現(xiàn)這2個(gè)地址不同,就會認(rèn)為是2個(gè)不同的對象,就會出現(xiàn)相同的數(shù)據(jù)
    }
}
class User{
    String id;
    String name;
    // ctrl + o 就可以啦
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}

如何如果讓一個(gè)對象的id和name相同,就讓它識別為是同一個(gè)數(shù)據(jù)

如果讓一個(gè)對象的id和name相同,就讓它識別為是同一個(gè)數(shù)據(jù)呢?
是可以的。我們需要重寫2個(gè)方法;hashCode 和 equals
因?yàn)? HashSet是在存儲數(shù)據(jù)的時(shí)候,就是通過hashCode來操作的。
我們給定一個(gè)值(字符串), 通過操作得到存儲到哪一個(gè)位置。
當(dāng)然不同的值可能得到的存儲位置是一樣的。
如果出現(xiàn)這樣的情況,他會去比較他們的equals。
如果相等,會把這個(gè)數(shù)據(jù)(后面這個(gè)新增的數(shù)據(jù))丟棄,什么都不做。
如果不相等,這個(gè)時(shí)候他會使用鏈表它裝在一起哈。
我們也可以從這里得出結(jié)論:HashSet的底層是:數(shù)組+鏈表的結(jié)構(gòu)來進(jìn)行存儲數(shù)據(jù)的

重寫hashCode 和 equals

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
public class Java01 {
    public static void main(String[] args) {
       HashSet setList = new HashSet();
       User u1 = new User();
       User u2 = new User();
        u1.id = 2025;
        u1.name = "張三";
        u2.id = 2025;
        u2.name = "張三";
        setList.add(u1);
        setList.add(u2);
        // [User [id=2025, name=張三]] 現(xiàn)在數(shù)據(jù)就不會重復(fù)了
        System.out.println(setList);
    }
}
class User{
    int id;
    String name;
    //    重寫方法的快捷鍵 ctrl+o
    @Override
    //  類似與我們的內(nèi)存地址,我們使用id來判斷
    public int hashCode() {
        return id;
    }
    @Override
    // 判斷2個(gè)對象的屬性是否完全相同
    public boolean equals(Object obj) {
        if(obj instanceof User) {
            //因?yàn)檫@個(gè)對象是User類型的,我們可以使用強(qiáng)制轉(zhuǎn)換
            User u = (User)obj;
            //判斷對象的屬性是否相同,這里為啥使用equals,等會回說一下
            if(u.id==this.id && u.name.equals(this.name)) {
                return true;
            }else{
                return false;
            }
        }else{
            // 如果不是,直接返回false
            return false;
        }
    }
    @Override
    public String toString() {
         return "User [id=" + id + ", name=" + name + "]";
    }
}

HashSet的底層是:數(shù)組+鏈表的結(jié)構(gòu)來進(jìn)行存儲數(shù)據(jù)的

== 和 equals的區(qū)別

1,當(dāng)使用 == 比較基本數(shù)據(jù)類型,它比較的是兩個(gè)變量的值是否相等。
2,當(dāng)使用 == 比較引用數(shù)據(jù)類型(如對象)時(shí),它比較的是對象的內(nèi)存地址是否相等,即它們是否引用同一內(nèi)存地址。
3,equals是Object類中的一個(gè)方法,用于比較同一類的兩個(gè)對象的內(nèi)容是否相等。

equals的比較邏輯

equals方法首先檢查兩個(gè)對象是否為同一類的實(shí)例(即類是否相等)。
如果不屬于同一類,則對象肯定不相等。
如果類相等,equals方法將逐一比較兩個(gè)對象的字段或?qū)傩?,以確定它們是否相等。

適用場景:

對于基本數(shù)據(jù)類型,== 用于比較值是否相
對于引用數(shù)據(jù)類型:如對象,通常使用 equals 方法進(jìn)行內(nèi)容比較。

方法重寫:

== 的行為固定,不可更改。
equals 方法可以在自定義類中重寫,以實(shí)現(xiàn)特定的比較邏輯。

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

相關(guān)文章

  • SpringBoot項(xiàng)目中使用緩存Cache的正確方法分享

    SpringBoot項(xiàng)目中使用緩存Cache的正確方法分享

    緩存可以通過將經(jīng)常訪問的數(shù)據(jù)存儲在內(nèi)存中,減少底層數(shù)據(jù)源如數(shù)據(jù)庫的壓力,從而有效提高系統(tǒng)的性能和穩(wěn)定性。本文就來講講SpringBoot項(xiàng)目中使用緩存Cache的正確姿勢吧
    2023-04-04
  • idea如何關(guān)閉頁面顯示的瀏覽器圖標(biāo)

    idea如何關(guān)閉頁面顯示的瀏覽器圖標(biāo)

    這篇文章主要介紹了idea如何關(guān)閉頁面顯示的瀏覽器圖標(biāo)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 深入理解Spring MVC的數(shù)據(jù)轉(zhuǎn)換

    深入理解Spring MVC的數(shù)據(jù)轉(zhuǎn)換

    這篇文章主要給大家介紹了關(guān)于Spring MVC數(shù)據(jù)轉(zhuǎn)換的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起看看吧。
    2017-09-09
  • 教你開發(fā)腳手架集成Spring?Boot?Actuator監(jiān)控的詳細(xì)過程

    教你開發(fā)腳手架集成Spring?Boot?Actuator監(jiān)控的詳細(xì)過程

    這篇文章主要介紹了開發(fā)腳手架集成Spring?Boot?Actuator監(jiān)控的詳細(xì)過程,集成包括引入依賴配置文件及訪問驗(yàn)證的相關(guān)知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • Java集合之Map接口的實(shí)現(xiàn)類精解

    Java集合之Map接口的實(shí)現(xiàn)類精解

    Map提供了一種映射關(guān)系,其中的元素是以鍵值對(key-value)的形式存儲的,能夠?qū)崿F(xiàn)根據(jù)key快速查找value;Map中的鍵值對以Entry類型的對象實(shí)例形式存在;鍵(key值)不可重復(fù),value值可以重復(fù),一個(gè)value值可以和很多key值形成對應(yīng)關(guān)系,每個(gè)建最多只能映射到一個(gè)值
    2021-09-09
  • SpringBoot整合freemarker實(shí)現(xiàn)代碼生成器

    SpringBoot整合freemarker實(shí)現(xiàn)代碼生成器

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何整合freemarker實(shí)現(xiàn)一個(gè)簡單的代碼生成器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-03-03
  • SpringBoot攔截器不生效的問題解決

    SpringBoot攔截器不生效的問題解決

    很多開發(fā)者會遇到一個(gè)常見的問題,攔截器配置了卻不生效,本文主要介紹了SpringBoot攔截器不生效的問題解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-09-09
  • Java靜態(tài)方法不能調(diào)用非靜態(tài)成員的原因分析

    Java靜態(tài)方法不能調(diào)用非靜態(tài)成員的原因分析

    在Java中,靜態(tài)方法是屬于類的方法,而不是屬于對象的方法,它可以通過類名直接調(diào)用,無需創(chuàng)建對象實(shí)例,非靜態(tài)成員指的是類的實(shí)例變量和實(shí)例方法,它們需要通過對象實(shí)例才能訪問和調(diào)用,本文小編將和大家一起探討Java靜態(tài)方法為什么不能調(diào)用非靜態(tài)成員
    2023-10-10
  • RabbitMQ?集群部署解決方案

    RabbitMQ?集群部署解決方案

    這篇文章詳細(xì)介紹了如何在三臺CentOS?7服務(wù)器上配置和設(shè)置RabbitMQ集群,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-12-12
  • IDEA調(diào)試小技巧之Evaluate調(diào)試工具詳解

    IDEA調(diào)試小技巧之Evaluate調(diào)試工具詳解

    這篇文章主要介紹了IDEA調(diào)試小技巧之Evaluate調(diào)試工具,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09

最新評論

寿光市| 辛集市| 梁河县| 农安县| 新干县| 安平县| 青神县| 五指山市| 德兴市| 辽中县| 沾益县| 大邑县| 兴化市| 工布江达县| 庆城县| 永泰县| 永昌县| 大兴区| 东城区| 开化县| 萝北县| 汤阴县| 城口县| 甘泉县| 全州县| 屏南县| 新丰县| 上蔡县| 祁阳县| 新安县| 南乐县| 沭阳县| 卢龙县| 张家川| 莆田市| 曲松县| 沙田区| 类乌齐县| 巫山县| 北辰区| 杭锦旗|