日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Collection集合中的 contains 和 remove 使用深入——为什么要重写equals() ?

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Collection集合中的 contains 和 remove 使用深入——为什么要重写equals() ? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

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

源碼剖析

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

先看看contains:

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

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

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

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

同樣看看remove方法:

同樣,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放入array1array1.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放入array1array1.add(num1);// 定義一個num2也為1000Integer 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對象u1User 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對象u1User 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() ?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 毛片网止 | 69亚洲精品久久久蜜桃小说 | 亚洲妇女无套内射精 | 国产日韩视频在线 | 黄色一级免费视频 | 夜夜艹| 亚洲欧美另类在线视频 | 日韩一级在线观看 | 99热精品久久 | 久久丫精品国产亚洲av不卡 | 日韩在线1 | 粉嫩精品久久99综合一区 | 日韩av第一页 | 成人免费区一区二区三区 | 特黄特色大片免费播放器使用方法 | 国产一区二区麻豆 | 91精品国产色综合久久不卡98 | 成人特级片 | 老司机午夜剧场 | 亚州精品国产精品乱码不99按摩 | 国产在线看一区 | 亚洲熟妇无码一区二区三区 | 国产乱淫精品一区二区三区毛片 | 日本久久伊人 | 在线小视频 | 2019中文字幕在线 | 久草电影网站 | 国产精品久久久久久久久久久久 | 最新永久地址 | 少女情窦初开的第4集在线观看 | 无码一区二区三区 | 日韩一区在线播放 | 九九热这里有精品 | cao在线 | 亚洲最大视频网站 | 国产麻豆a毛片 | 国产精品露脸视频 | 久久阁| 成人在线观看一区二区 | 欧美日韩中文国产一区发布 | 四虎精品一区二区三区 | 国产精品自产拍在线观看 | 好吊日精品视频 | 欧美黄色小说 | 69性视频| 每日更新av| 一级黄色片网站 | 国产三级91 | 国产又粗又猛又爽又黄无遮挡 | 黑色丝袜吻戏亲胸摸腿 | 天天舔天天爽 | 97精品国产97久久久久久春色 | 国产一区二区三区播放 | 一区二区三区色 | 日本高清不卡一区 | 日韩黄色三级视频 | 五月情婷婷 | 精品国产无码一区二区三区 | 亚洲一二三区视频 | 黄色高清在线观看 | 亚洲AV乱码国产精品观看麻豆 | 成人一级片视频 | 草久网 | 亚洲欧美亚洲 | 713电影免费播放国语 | 极品91 | 熟妇高潮喷沈阳45熟妇高潮喷 | 天天狠天天干 | 亚洲拍拍视频 | 国产成人在线观看免费 | 狠狠ri | 一级少妇女片 | 青春草久久| 韩国伦理片在线观看 | 国产成人av网站 | 男男黄色片 | 超碰在线最新地址 | 姑娘第5集高清在线观看 | 少妇精品久久久一区二区三区 | 亚洲制服丝袜一区 | 午夜三级视频 | 久国产 | 欧美小视频在线 | 欧美成人综合视频 | 高清视频在线播放 | 日本a在线观看 | 精品视频第一页 | 蜜桃视频污在线观看 | 国内精品偷拍视频 | 韩国特级毛片 | 欧美啪啪网| 夜夜综合网 | 国产精品视频免费网站 | 亚洲av无码一区二区二三区 | 日韩黄色在线观看 | 亲嘴脱内衣内裤 | 国产在线三区 | 男女做爰猛烈吃奶啪啪喷水网站 | 永久免费看片在线播放 |