一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 剖析Java中在Collection集合中使用contains和remove為什么要重寫equals

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

2022-01-11 01:00YXXYX Java教程

這篇文章主要介紹了Collection集合的contains和remove方法詳解remove以及相關的經驗技巧,通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下

 

引言

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

 

源碼剖析

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

先看看contains:

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

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

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

可以看到,indexOf又進一步調用了indexOfRange方法,我們還需要深入看看這個方法:

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

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

為什么是幾乎所有?
因為還是有特例的:SUN公司已經把String類和包裝類的equals方法重寫了,所以對于這兩種我們不需要重寫equals!

同樣看看remove方法:

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

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

所以這里可以得出一個結論:
Collection集合中的remove方法和contains方法底層都會調用equals,所以只要放在集合中的類型,都要重寫equals方法;
因為對對象的地址的比較沒有什么意義,我們實際上需要的是對象內容間的比較;

 

實例測試

知道了結論,就來寫幾個代碼測試一下:

 

String類和包裝類的特殊情況

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

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

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

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


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

輸出結果:

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

 

自定義類型

這是equals重寫的情況,接下來我自定義一個類型,看看沒有重寫會發生什么;

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

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

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

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

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

輸出結果:

array中是否包含新創建的對象?false
移除后u1是否存在?true

可以看到,我自定義的User方法里沒有重寫equals方法,所以當調用contains和remove時,雖然傳入的對象內容和u1的對象內容相同都為“張三”,但是實際上比較的卻是對象的地址;

接下來我重寫User的equals方法,看看結果如何;

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

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

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

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

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

    // 重寫equals方法 ,通過name進行比較
    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);
    }
}

輸出結果:

array中是否包含新創建的對象?true
移除后u1是否存在?false

我只是重寫了一個equals方法,其他地方都沒變,結果完全不同;

所以這就驗證了之前的結論:contains 和 remove 底層實現都調用了equals方法;

 

總結

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

希望各位在Java學習中養成好習慣,要時刻惦記著equals的重寫,不然如果做了一個項目你連錯在哪里都不好找到;

到此這篇關于剖析在Collection集合中使用contains和remove為什么要重寫equals的文章就介紹到這了,更多相關Collection 重寫 equals內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/YXXXYX/article/details/120370688

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
主站蜘蛛池模板: 日韩精品亚洲专区在线影视 | 91精品国产色综合久久不卡蜜 | 四虎影视国产精品婷婷 | 掀开奶罩边躁狠狠躁软学生 | 日本无吗免费一二区 | 77色视频在线| 亚洲一卡2卡4卡5卡6卡残暴在线 | 我与么公激情性完整视频 | chinese高中生gay男同 | 99er在线视频 | 男人扒开| 公园暴露娇妻小说 | 色综合天天综合网国产人 | 国产亚洲精品看片在线观看 | 国产福利一区二区精品视频 | 男女拍拍拍免费视频网站 | 欧美日韩国产最新一区二区 | 四虎影视永久在线 | 好吊日在线 | 日本老妇人乱视频 | 脱了白丝校花的内裤猛烈进入 | 精品精品久久宅男的天堂 | 网红刘婷hd国产高清 | avtt天堂在线| 天堂在线国产 | 妹妹骑上来蹭着蹭着就射了 | 国产精品视频一区二区三区经 | 日韩专区在线观看 | 日本中文字幕一区二区三区不卡 | 奇米影视在线观看 | www.俺去| 麻生希无码 | 我的男友是消防员在线观看 | 成人国产一区二区 | 虎四免费入口 | 成人青青草 | 国产精品天天影视久久综合网 | 国产一卡2卡3卡4卡公司科普 | 红色播放器 | 精品丰满人妻无套内射 | 欧美伦乱 |