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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ArrayList类contains方法实现原理

發(fā)布時間:2025/3/12 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ArrayList类contains方法实现原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

以ArrayList集合示例

思考:contains方法如何執(zhí)行?

public static void main(String [] args){List<String> list=new ArrayList<String>(); list.add("張三"); System.out.println(list.contains("張三"); }
分析contains底層代碼
public boolean contains(Object o) { //o為傳入的參數(shù),此時的o為上轉(zhuǎn)型對象return indexOf(o) >= 0; //調(diào)用下面indexOf(Object o)方法并把參數(shù)傳入//因為 下面indexOf方法的返回值為int類型 indexOf方法的返回值 大于等于0 便會返回true 否則反之}public int indexOf(Object o) { //o為此時方法的形參 參數(shù)為上面調(diào)用方法時傳進來的參數(shù)return indexOfRange(o, 0, size); //調(diào)用下面indexOfRange(Object o, int start, int end)方法 size是當前調(diào)用contains方法集合元素的個數(shù) 0是因為 集合的下標是從0開始的 o 是由外面?zhèn)鬟M來的值}int indexOfRange(Object o, int start, int end) {Object[] es = elementData; //把當前調(diào)用contains方法集合里面的每個元素放到這個數(shù)組里面if (o == null) { //判斷o是否為null 當前 o 是有外部傳進來的值 所以肯定不為nullfor (int i = start; i < end; i++) {if (es[i] == null) {return i;}}} else { //因為上面o不是null 所以便會走else塊for (int i = start; i < end; i++) { //因為上面使用該方法時傳進來值 此時start =0 end 時當前集合元素的個數(shù)if (o.equals(es[i])) { //o代表外面?zhèn)鬟M來的值 跟es數(shù)組中的每一位元素進行equals比較//此時需要注意 此時出現(xiàn)了多態(tài) 因為equals 在object中定義了這個方法在編譯時會調(diào)用Object中的equals的方法//但是 在運行時會 會調(diào)用Object類的子類中所重寫的equals方法 那么這時 誰調(diào)用equals方法 便會進入到當前調(diào)用類中并且使用equals方法return i; //如果找到便會返回當前的int類型的下標}}}return -1; //如果if和else 都不滿足 便會返回-1}
String類中 equals比較時的代碼

因為我們傳進來的Object o是String類型的 那么我們此時便會調(diào)用String中重寫后的equals方法

public boolean equals(Object anObject) { //注意 注意 注意 重要的事情 說三遍//equals 是上面這個 indexOfRange(Object o, int start, int end)方法中變量o調(diào)用的但是 equals方法中的行參是上面這個 indexOfRange(Object o, int start, int end)方法中的es[]數(shù)組 ,數(shù)組里面又是儲存的當前調(diào)用contains方法集合里面的每個元素 if (this == anObject) { //this代表當前 誰調(diào)用便會 指向誰 此時this指向調(diào)用equals 方法的o anObject 是equals方法的形參 也就是 es[]數(shù)組中的每一個元素,進行==地址比較如果地址相等返回true return true;}if (anObject instanceof String) { //判斷equals 方法的形參是否為String類型String aString = (String)anObject; //如果上面判斷成功 便會把equals方法的形參轉(zhuǎn)為String類型 并賦值給aString變量if (!COMPACT_STRINGS || this.coder == aString.coder) { //COMPACT_STRINGS 是String 類中定義的實參 值為false (|| 短路與 滿足一個條件即可) COMPACT_STRINGS取反為true 進入 return StringLatin1.equals(value, aString.value); //// 調(diào)用StringLatin1類中的equals方法 里面的兩個參數(shù)是 你要比較的兩個值 并且會把這兩個值 拆分為一個一個放入到byte類型的數(shù)組中}}return false;}
StringLatin1類中的equals方法
public static boolean equals(byte[] value, byte[] other) { //里面兩個形參 是上面String類中equals 調(diào)用該類中equals 方法傳入的值if (value.length == other.length) { //先比較兩個數(shù)組的長度 如果長度不同 就不會進入 for (int i = 0; i < value.length; i++) { //循環(huán)比較if (value[i] != other[i]) { //分別比較兩個數(shù)組中的每一位元素return false; //只要 有一位不用便會返回false}}return true; //如果兩個數(shù)組里面所存儲的每一位元素都相同 便會返回true }return false; //如果沒進if判斷 便會直接返回false}
自定義類中的equals方法

此時我們用Student類 來舉例

因為 在上面說明過 equals 在Object中 如果 你調(diào)用equals 的類 沒有重寫 equals 便會調(diào)用Object 中的 equals 方法 所以 我們此時要在自定義類中重寫equals方法

@Overridepublic boolean equals(Object anObject) { //equals 是上面這個 indexOfRange(Object o, int start, int end)方法中變量o調(diào)用的但是 equals方法中的行參是上面這個 indexOfRange(Object o, int start, int end)方法中的es[]數(shù)組 ,數(shù)組里面又是儲存的當前調(diào)用contains方法集合里面的每個元素if(anObject instanceof Student) { //此時我們以 Student 來舉例 判斷equals 方法的形參是否為Student類型Student stu=(Student)anObject; //如果上面判斷成功 便會把equals方法的形參轉(zhuǎn)為Student類型 并賦值給stu變量return this.id.equals(stu.id); this代表當前 誰調(diào)用便會 指向誰 此時this指向調(diào)用equals方法的這個自定義類 那么此時我們用這個類中id 跟 傳進來的stu變量里的id 進行比較 比較方式 和上面的講解的一樣}


ArrayList中contains的方法及原理

ArrayList中contains的方法及原理

contains源代碼如下:

這里的O代表contains方法中的參數(shù)對象,如果數(shù)值大于等于0,就會返回true。

O調(diào)用什么樣的equals方法取決于O是什么類型

contains方法中的參數(shù)類型如果是String類型,則調(diào)用String對象中的equals方法

contains方法中的參數(shù)類型如果是基本數(shù)據(jù)類型的包裝類,則調(diào)用包裝類中的equals方法

contains方法中的參數(shù)類型如果是類部類型,則調(diào)用類部類型中的equals方法

String類型:

這時的結(jié)果輸出為true。

1:當執(zhí)行到list.contains(“李坦克”)時,調(diào)用了contains方法,其中張大炮賦值給了O,O即為String類

2:接著在調(diào)用indexOf方法,因為O !=null,所以進入else{ }語句中,O去調(diào)用String類的equals方法,先比較地址,在比較每一個字符,有一樣相同即返回true,與集合中的元素進行比較,一旦找到相同的,則返回此時對應的i。

3:這時跳轉(zhuǎn)回contains方法中,因為此時i>=0,所以返回true。

4:如果O為null,就會執(zhí)行if語句,接著通過for循環(huán)去判斷集合中是否有值為null的元素,若有則返回i,即返回true;如果遍歷完集合沒有找到null這個元素,則會跳出if語句,執(zhí)行最后一條語句:return -1;,所以最后會返回false。

*自定義類型:*

*未重寫equals方法:*

這里首先定義一個學生類,這里返回的是false。

1:執(zhí)行到list.contains(new Student(“20”))時,跳轉(zhuǎn)contains方法,創(chuàng)建一個Student對象20賦值給O,所以O為Student類。

2:接著就是跳轉(zhuǎn)到indexOf方法中,因為O !=null,進入else語句中,O本來是要調(diào)用Student中的equals方法的,但是Student類中沒有重寫equals方法,所以就要去調(diào)用Student父類Object類中的equals方法,而Object中的equals方法是比較地址,當我們每創(chuàng)建一個對象,都會new一個新的空間,也就是每一個對象都會有一個新地址,所以O的地址與集合中的每個元素地址都不一樣,所有最終會返回false

3:假如O=null跟String類型一樣。

重寫equal方法:

重寫的equals方法中,obj就是集合中每個元素,判斷傳進來的類型是否為Student類創(chuàng)建出來的對象或者是Student的子類,如果是就執(zhí)行語句,不是返回false;如果是的話,將obj下轉(zhuǎn)為Student類型,這里this.id是指誰調(diào)用equals方法就是誰的id,這里t.id是指傳進來的obj下轉(zhuǎn)型t的id。

為什么這里重寫equals方法后返回的就是true了。

1:當代碼執(zhí)行到list.contains(new Student(“20”))時,跳轉(zhuǎn)contains方法,創(chuàng)建一個新的對象20賦值給O,這時O就是Student類

2:在調(diào)用indexOf方法,因為O !=0,所以直接進入else語句中,因為這里我們在Student類中重寫了equals方法,所以O去調(diào)用Student類中重寫后的equals方法,我們定義的equals方法也是先比較地址,在比較字符,所以會返回true,即條件滿足進入if語句,執(zhí)行return i;

3:跳轉(zhuǎn)回contains方法中,此時i>=0;所以最終會返回true。

4:如果這里O還是為null跟String類型一樣

總結(jié)

以上是生活随笔為你收集整理的ArrayList类contains方法实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。