ArrayList类contains方法实现原理
以ArrayList集合示例
思考:contains方法如何執行?
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為傳入的參數,此時的o為上轉型對象return indexOf(o) >= 0; //調用下面indexOf(Object o)方法并把參數傳入//因為 下面indexOf方法的返回值為int類型 indexOf方法的返回值 大于等于0 便會返回true 否則反之}public int indexOf(Object o) { //o為此時方法的形參 參數為上面調用方法時傳進來的參數return indexOfRange(o, 0, size); //調用下面indexOfRange(Object o, int start, int end)方法 size是當前調用contains方法集合元素的個數 0是因為 集合的下標是從0開始的 o 是由外面傳進來的值}int indexOfRange(Object o, int start, int end) {Object[] es = elementData; //把當前調用contains方法集合里面的每個元素放到這個數組里面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 時當前集合元素的個數if (o.equals(es[i])) { //o代表外面傳進來的值 跟es數組中的每一位元素進行equals比較//此時需要注意 此時出現了多態 因為equals 在object中定義了這個方法在編譯時會調用Object中的equals的方法//但是 在運行時會 會調用Object類的子類中所重寫的equals方法 那么這時 誰調用equals方法 便會進入到當前調用類中并且使用equals方法return i; //如果找到便會返回當前的int類型的下標}}}return -1; //如果if和else 都不滿足 便會返回-1}String類中 equals比較時的代碼
因為我們傳進來的Object o是String類型的 那么我們此時便會調用String中重寫后的equals方法
public boolean equals(Object anObject) { //注意 注意 注意 重要的事情 說三遍//equals 是上面這個 indexOfRange(Object o, int start, int end)方法中變量o調用的但是 equals方法中的行參是上面這個 indexOfRange(Object o, int start, int end)方法中的es[]數組 ,數組里面又是儲存的當前調用contains方法集合里面的每個元素 if (this == anObject) { //this代表當前 誰調用便會 指向誰 此時this指向調用equals 方法的o anObject 是equals方法的形參 也就是 es[]數組中的每一個元素,進行==地址比較如果地址相等返回true return true;}if (anObject instanceof String) { //判斷equals 方法的形參是否為String類型String aString = (String)anObject; //如果上面判斷成功 便會把equals方法的形參轉為String類型 并賦值給aString變量if (!COMPACT_STRINGS || this.coder == aString.coder) { //COMPACT_STRINGS 是String 類中定義的實參 值為false (|| 短路與 滿足一個條件即可) COMPACT_STRINGS取反為true 進入 return StringLatin1.equals(value, aString.value); //// 調用StringLatin1類中的equals方法 里面的兩個參數是 你要比較的兩個值 并且會把這兩個值 拆分為一個一個放入到byte類型的數組中}}return false;}StringLatin1類中的equals方法
public static boolean equals(byte[] value, byte[] other) { //里面兩個形參 是上面String類中equals 調用該類中equals 方法傳入的值if (value.length == other.length) { //先比較兩個數組的長度 如果長度不同 就不會進入 for (int i = 0; i < value.length; i++) { //循環比較if (value[i] != other[i]) { //分別比較兩個數組中的每一位元素return false; //只要 有一位不用便會返回false}}return true; //如果兩個數組里面所存儲的每一位元素都相同 便會返回true }return false; //如果沒進if判斷 便會直接返回false}自定義類中的equals方法
此時我們用Student類 來舉例
因為 在上面說明過 equals 在Object中 如果 你調用equals 的類 沒有重寫 equals 便會調用Object 中的 equals 方法 所以 我們此時要在自定義類中重寫equals方法
@Overridepublic boolean equals(Object anObject) { //equals 是上面這個 indexOfRange(Object o, int start, int end)方法中變量o調用的但是 equals方法中的行參是上面這個 indexOfRange(Object o, int start, int end)方法中的es[]數組 ,數組里面又是儲存的當前調用contains方法集合里面的每個元素if(anObject instanceof Student) { //此時我們以 Student 來舉例 判斷equals 方法的形參是否為Student類型Student stu=(Student)anObject; //如果上面判斷成功 便會把equals方法的形參轉為Student類型 并賦值給stu變量return this.id.equals(stu.id); this代表當前 誰調用便會 指向誰 此時this指向調用equals方法的這個自定義類 那么此時我們用這個類中id 跟 傳進來的stu變量里的id 進行比較 比較方式 和上面的講解的一樣}ArrayList中contains的方法及原理
ArrayList中contains的方法及原理
contains源代碼如下:
這里的O代表contains方法中的參數對象,如果數值大于等于0,就會返回true。
O調用什么樣的equals方法取決于O是什么類型
contains方法中的參數類型如果是String類型,則調用String對象中的equals方法;
contains方法中的參數類型如果是基本數據類型的包裝類,則調用包裝類中的equals方法;
contains方法中的參數類型如果是類部類型,則調用類部類型中的equals方法;
String類型:
這時的結果輸出為true。
1:當執行到list.contains(“李坦克”)時,調用了contains方法,其中張大炮賦值給了O,O即為String類
2:接著在調用indexOf方法,因為O !=null,所以進入else{ }語句中,O去調用String類的equals方法,先比較地址,在比較每一個字符,有一樣相同即返回true,與集合中的元素進行比較,一旦找到相同的,則返回此時對應的i。
3:這時跳轉回contains方法中,因為此時i>=0,所以返回true。
4:如果O為null,就會執行if語句,接著通過for循環去判斷集合中是否有值為null的元素,若有則返回i,即返回true;如果遍歷完集合沒有找到null這個元素,則會跳出if語句,執行最后一條語句:return -1;,所以最后會返回false。
*自定義類型:*
*未重寫equals方法:*
這里首先定義一個學生類,這里返回的是false。
1:執行到list.contains(new Student(“20”))時,跳轉contains方法,創建一個Student對象20賦值給O,所以O為Student類。
2:接著就是跳轉到indexOf方法中,因為O !=null,進入else語句中,O本來是要調用Student中的equals方法的,但是Student類中沒有重寫equals方法,所以就要去調用Student父類Object類中的equals方法,而Object中的equals方法是比較地址,當我們每創建一個對象,都會new一個新的空間,也就是每一個對象都會有一個新地址,所以O的地址與集合中的每個元素地址都不一樣,所有最終會返回false
3:假如O=null跟String類型一樣。
重寫equal方法:
重寫的equals方法中,obj就是集合中每個元素,判斷傳進來的類型是否為Student類創建出來的對象或者是Student的子類,如果是就執行語句,不是返回false;如果是的話,將obj下轉為Student類型,這里this.id是指誰調用equals方法就是誰的id,這里t.id是指傳進來的obj下轉型t的id。
為什么這里重寫equals方法后返回的就是true了。
1:當代碼執行到list.contains(new Student(“20”))時,跳轉contains方法,創建一個新的對象20賦值給O,這時O就是Student類
2:在調用indexOf方法,因為O !=0,所以直接進入else語句中,因為這里我們在Student類中重寫了equals方法,所以O去調用Student類中重寫后的equals方法,我們定義的equals方法也是先比較地址,在比較字符,所以會返回true,即條件滿足進入if語句,執行return i;
3:跳轉回contains方法中,此時i>=0;所以最終會返回true。
4:如果這里O還是為null跟String類型一樣
總結
以上是生活随笔為你收集整理的ArrayList类contains方法实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: @Autowired注解能用在stati
- 下一篇: AI成为世界互联网大会重要议题 第四范式