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

剖析Java中在Collection集合中使用contains和remove為什么要重寫(xiě)equals

 更新時(shí)間:2021年09月22日 09:14:10   作者:YXXYX  
這篇文章主要介紹了Collection集合的contains和remove方法詳解remove以及相關(guān)的經(jīng)驗(yàn)技巧,通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

引言

在Collection集合中:
contains方法是判斷一個(gè)集合里面是否包含指定元素,如果有則返回true;
remove方法是從集合中刪除指定元素的單個(gè)實(shí)例;
這兩個(gè)方法看起很簡(jiǎn)單,用起來(lái)也很簡(jiǎn)單,同樣也非常常用;但是,它們到底是怎么匹配到相應(yīng)的元素呢?

源碼剖析

以ArrayList為例,我們分析一下ArrayList中的contains和remove的源碼;

先看看contains:

在這里插入圖片描述

這里看到比較的對(duì)象是一個(gè)Object類,變量名為 o(就是是否包含 o ),并且調(diào)用了一個(gè)indexOf方法,接下來(lái)我們進(jìn)一步看看indexOf源碼:

在這里插入圖片描述

可以看到,indexOf又進(jìn)一步調(diào)用了indexOfRange方法,我們還需要深入看看這個(gè)方法:

在這里插入圖片描述

這里可以發(fā)現(xiàn),indexOfRange中 o 調(diào)用了equals方法(藍(lán)色部分)!
我們知道:equals方法是判斷兩個(gè)對(duì)象是否相等,但是默認(rèn)情況下比較的是對(duì)象的地址,如果想要比較對(duì)象的內(nèi)容就需要重寫(xiě)equals方法;
那么這個(gè)contains調(diào)用了equals方法,所以,contains判斷一個(gè)集合中是否包含某個(gè)元素其實(shí)就是通過(guò)對(duì)象地址比較的了;
這并不是我們想要的結(jié)果,所以幾乎所有放在集合中的類型,都需要重寫(xiě)equals方法!

為什么是幾乎所有?
因?yàn)檫€是有特例的:SUN公司已經(jīng)把String類和包裝類的equals方法重寫(xiě)了,所以對(duì)于這兩種我們不需要重寫(xiě)equals!

同樣看看remove方法:

在這里插入圖片描述

同樣,remove方法也是通過(guò)equals方法比較元素然后移除的;

所以這里可以得出一個(gè)結(jié)論:
Collection集合中的remove方法和contains方法底層都會(huì)調(diào)用equals,所以只要放在集合中的類型,都要重寫(xiě)equals方法;
因?yàn)閷?duì)對(duì)象的地址的比較沒(méi)有什么意義,我們實(shí)際上需要的是對(duì)象內(nèi)容間的比較;

實(shí)例測(cè)試

知道了結(jié)論,就來(lái)寫(xiě)幾個(gè)代碼測(cè)試一下:

String類和包裝類的特殊情況

對(duì)于 String類型和包裝類,SUN公司重寫(xiě)了equals方法,所以我們先測(cè)試一下這兩種情況:

import java.util.ArrayList;
import java.util.Collection;

// 結(jié)論:Collection接口中的remove方法和contains方法底層都會(huì)調(diào)用equals,
// 所以存放在一個(gè)集合中的類型,要重寫(xiě)它的equals方法
// (但是String和包裝類的equals方法已經(jīng)重寫(xiě)過(guò)了,不用重寫(xiě))
public class CollectionTest02 {
    public static void main(String[] args) {
        // 這里以ArrayList為例
        Collection array1 = new ArrayList();

        // String類:
        String s1 = "Hello";
        // 將s1放入array1
        array1.add(s1);
        // 定義一個(gè)s2也為 "Hello",那么調(diào)用contains是否會(huì)包含s2?
        String s2 = "Hello";
        System.out.println("array1是否包含s2?" + array1.contains(s2)); // true
        // 因?yàn)閍rray1中放入的是s1,如果移除s2,s1會(huì)不會(huì)被移除呢?
        array1.remove(s2);
        System.out.println("移除s2后s1是否還在array1中?" + array1.contains(s1)); // false


        // 包裝類也同樣:
        Integer num1 = 1000;
        // 將num1放入array1
        array1.add(num1);
        // 定義一個(gè)num2也為1000
        Integer num2 = 1000;
        System.out.println("array1是否包含num2?" + array1.contains(num2)); // true
        // 移除num2觀察num1是否會(huì)被移除
        array1.remove(num2);
        System.out.println("移除num2后num1是否還在array1中?" + array1.contains(num1)); // false
    }
}

輸出結(jié)果:

array1是否包含s2?true
移除s2后s1是否還在array1中?false
array1是否包含num2?true
移除num2后num1是否還在array1中?false

自定義類型

這是equals重寫(xiě)的情況,接下來(lái)我自定義一個(gè)類型,看看沒(méi)有重寫(xiě)會(huì)發(fā)生什么;

import java.util.ArrayList;
import java.util.Collection;

public class CollectionTest03 {
    public static void main(String[] args) {
        // 還是以ArrayList為例
        Collection array = new ArrayList();

        // 創(chuàng)建一個(gè)User對(duì)象u1
        User u1 = new User("張三");
        // 將u1對(duì)象放入array中
        array.add(u1);
        // 再創(chuàng)建一個(gè)User對(duì)象,使其內(nèi)容和u1相同都為"張三",那么調(diào)用contains是否會(huì)包含該對(duì)象呢?
        System.out.println("array中是否包含新創(chuàng)建的對(duì)象?" + array.contains(new User("張三"))); // false
        // 移除一個(gè)內(nèi)容為"張三"的新的對(duì)象,u1是否會(huì)被移除?
        array.remove(new User("張三"));
        System.out.println("移除后u1是否存在?" + array.contains(u1)); // true
    }
}

// 自己定義一個(gè)User類
class User {
    // 成員變量:姓名
    private String name;

    // 默認(rèn)構(gòu)造
    User() {}
    // 有參構(gòu)造:初始化姓名
    User(String name) {
        this.name = name;
    }
}

輸出結(jié)果:

array中是否包含新創(chuàng)建的對(duì)象?false
移除后u1是否存在?true

可以看到,我自定義的User方法里沒(méi)有重寫(xiě)equals方法,所以當(dāng)調(diào)用contains和remove時(shí),雖然傳入的對(duì)象內(nèi)容和u1的對(duì)象內(nèi)容相同都為“張三”,但是實(shí)際上比較的卻是對(duì)象的地址;

接下來(lái)我重寫(xiě)User的equals方法,看看結(jié)果如何;

import java.util.ArrayList;
import java.util.Collection;

public class CollectionTest03 {
    public static void main(String[] args) {
        // 還是以ArrayList為例
        Collection array = new ArrayList();

        // 創(chuàng)建一個(gè)User對(duì)象u1
        User u1 = new User("張三");
        // 將u1對(duì)象放入array中
        array.add(u1);
        // 再創(chuàng)建一個(gè)User對(duì)象,使其內(nèi)容和u1相同都為"張三",那么調(diào)用contains是否會(huì)包含該對(duì)象呢?
        System.out.println("array中是否包含新創(chuàng)建的對(duì)象?" + array.contains(new User("張三"))); // true
        // 移除一個(gè)內(nèi)容為"張三"的新的對(duì)象,u1是否會(huì)被移除?
        array.remove(new User("張三"));
        System.out.println("移除后u1是否存在?" + array.contains(u1)); // false
    }
}

// 自己定義一個(gè)User類
class User {
    // 成員變量:姓名
    private String name;

    // 默認(rèn)構(gòu)造
    User() {}
    // 有參構(gòu)造:初始化姓名
    User(String name) {
        this.name = name;
    }

    // 重寫(xiě)equals方法 ,通過(guò)name進(jìn)行比較
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return name.equals(user.name);
    }
}

輸出結(jié)果:

array中是否包含新創(chuàng)建的對(duì)象?true
移除后u1是否存在?false

我只是重寫(xiě)了一個(gè)equals方法,其他地方都沒(méi)變,結(jié)果完全不同;

所以這就驗(yàn)證了之前的結(jié)論:contains 和 remove 底層實(shí)現(xiàn)都調(diào)用了equals方法;

總結(jié)

其實(shí)這篇文章就是分析一下contains 和 remove 底層實(shí)現(xiàn),主要想說(shuō)的還是那一句話:
Collection集合中的remove方法和contains方法底層都會(huì)調(diào)用equals,所以只要放在集合中的類型,都要重寫(xiě)equals方法;(String和包裝類除外)

希望各位在Java學(xué)習(xí)中養(yǎng)成好習(xí)慣,要時(shí)刻惦記著equals的重寫(xiě),不然如果做了一個(gè)項(xiàng)目你連錯(cuò)在哪里都不好找到;

到此這篇關(guān)于剖析在Collection集合中使用contains和remove為什么要重寫(xiě)equals的文章就介紹到這了,更多相關(guān)Collection 重寫(xiě) equals內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 學(xué)生信息管理系統(tǒng)java版

    學(xué)生信息管理系統(tǒng)java版

    這篇文章主要為大家詳細(xì)介紹了java學(xué)生信息管理系統(tǒng)源代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Mybatis?Web中的數(shù)據(jù)庫(kù)操作方法舉例詳解

    Mybatis?Web中的數(shù)據(jù)庫(kù)操作方法舉例詳解

    Mybatis是一款優(yōu)秀的持久化框架,用于簡(jiǎn)化JDBC的開(kāi)發(fā),下面這篇文章主要給大家介紹了關(guān)于Mybatis?Web中數(shù)據(jù)庫(kù)操作方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • Java集合框架之LinkedHashSet類解讀

    Java集合框架之LinkedHashSet類解讀

    這篇文章主要介紹了Java集合框架之LinkedHashSet類解讀,LinkedHashSet是HashSet的有序版本,它跨所有元素維護(hù)一個(gè)雙向鏈接的List,當(dāng)需要維護(hù)迭代順序時(shí),就使用這個(gè)類,當(dāng)遍歷HashSet時(shí),順序是不可預(yù)測(cè)的,需要的朋友可以參考下
    2023-09-09
  • Java基礎(chǔ)知識(shí)精通數(shù)組的使用

    Java基礎(chǔ)知識(shí)精通數(shù)組的使用

    數(shù)組對(duì)于每一門(mén)編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java?語(yǔ)言中提供的數(shù)組是用來(lái)存儲(chǔ)固定大小的同類型元素
    2022-04-04
  • 詳解Java中ThreadLocal類型及簡(jiǎn)單用法

    詳解Java中ThreadLocal類型及簡(jiǎn)單用法

    ThreadLocal實(shí)例通常是希望將狀態(tài)與線程關(guān)聯(lián)起來(lái)的類中的私有靜態(tài)字段,下面通過(guò)例子給大家詳細(xì)介紹Java中ThreadLocal類型及簡(jiǎn)單用法,感興趣的朋友跟隨小編一起看看吧
    2021-10-10
  • MybatisPlus之時(shí)間處理問(wèn)題

    MybatisPlus之時(shí)間處理問(wèn)題

    在數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí),阿里巴巴編碼規(guī)約建議使用gmt_create和gmt_modified命名時(shí)間字段,并設(shè)置為datetime類型,本文介紹了兩種自動(dòng)填充時(shí)間字段的實(shí)現(xiàn)方式:SQL級(jí)別和代碼級(jí)別(使用MyBatis?Plus),SQL級(jí)別通過(guò)設(shè)置默認(rèn)值和更新值為CURRENT_TIMESTAMP
    2024-09-09
  • 詳解Spring 框架中切入點(diǎn) pointcut 表達(dá)式的常用寫(xiě)法

    詳解Spring 框架中切入點(diǎn) pointcut 表達(dá)式的常用寫(xiě)法

    這篇文章主要介紹了詳解Spring 框架中切入點(diǎn) pointcut 表達(dá)式的常用寫(xiě)法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 通過(guò)代理類實(shí)現(xiàn)java連接數(shù)據(jù)庫(kù)(使用dao層操作數(shù)據(jù))實(shí)例分享

    通過(guò)代理類實(shí)現(xiàn)java連接數(shù)據(jù)庫(kù)(使用dao層操作數(shù)據(jù))實(shí)例分享

    java通過(guò)代理類實(shí)現(xiàn)數(shù)據(jù)庫(kù)DAO操作代碼分享,大家參考使用吧
    2013-12-12
  • Spring MVC中自定義攔截器的實(shí)例講解

    Spring MVC中自定義攔截器的實(shí)例講解

    下面小編就為大家?guī)?lái)一篇Spring MVC中自定義攔截器的實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Springboot2.x+ShardingSphere實(shí)現(xiàn)分庫(kù)分表的示例代碼

    Springboot2.x+ShardingSphere實(shí)現(xiàn)分庫(kù)分表的示例代碼

    這篇文章主要介紹了Springboot2.x+ShardingSphere實(shí)現(xiàn)分庫(kù)分表的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10

最新評(píng)論

武乡县| 新闻| 枣强县| 左权县| 汶上县| 京山县| 古田县| 建阳市| 中超| 海南省| 武汉市| 大兴区| 岳西县| 肇源县| 汝城县| 泉州市| 巍山| 区。| 罗平县| 寿光市| 顺平县| 临清市| 阜新| 古丈县| 来凤县| 读书| 容城县| 子长县| 伊金霍洛旗| 康马县| 依安县| 江都市| 吉林省| 寿宁县| 报价| 广南县| 崇信县| 曲松县| 邳州市| 东乌| 廊坊市|