浅谈contains方法底层代码实现及其使用示例

==与equals区别与关系

==:基本数据类型比较值是否相同;引用类型比较地址是否相同。示例代码如下:

int a = 10;
int b = 10;
System.out.println(a == b);
String c = "A";
String d = "B";
System.out.println(c == d);

equals:基本数据类型是不能直接调用方法的,所以equals只能用于引用类型,Object类中equals实质就是比较地址是否相同;Integer等包装类是比较类中存储的内容是否相同,String类中equals实质比较字符串内容是否相同。示例代码如下:

Object n = 10;
Object o = 10;
System.out.println(n.equals(o));
Integer e = 10;
Integer f = 10;
System.out.println(e.equals(f));
String g = "C";
String h = "D";
System.out.println(g.equals(h));

jdk14中contains方法底层代码实现

自定义一个测试类,用来调用contains方法,方便后面介绍contains方法底层代码实现:

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
	List<String> nameList = new ArrayList<>();//多态,编译时会调用List的方法,而实际运行时会调用ArrayList的方法
	nameList.add("Jack");
	String name = "Jack";
	System.out.println(nameList.contains(name));//nameList调用contains方法
	}

}

contains方法底层代码:

    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

    public int indexOf(Object o) {
        return indexOfRange(o, 0, size);
    }

    int indexOfRange(Object o, int start, int end) {
        Object[] es = elementData;
        if (o == null) {
           for (int i = start; i < end; i++) {
            if (es[i] == null) {
              return i;
            }
          }
        } else {
          for (int i = start; i < end; i++) {
            if (o.equals(es[i])) {
              return i;
            }
          }
        }
        return -1;
     }

public boolean contains(Object o) //name为传入参数——>o指向name所指向的对象——>即o里面存的为上转型对象name变量的地址

return indexOf(o) >= 0;//return返回值,并开始调用下面indexOf方法。

public int indexOf(Object o) {//indexOf方法中o指向contains方法o指向的对象——>indexOf方法o实质指向name对象

if (o == null) //该方法中已经为name对象赋值,所以o不为null——>o == null 这条语句false,继续往下执行

for (int i = start; i < end; i++)//for循环从start到end遍历nameList中每一个元素;其中start从indexOf方法传进来的值为0、end从indexOf方法传进来的值为size;之所以需要遍历集合是因为要将新传入的参数和原集合中的每个参数进行比较lai判断集合中是否存在特定参数

if (o.equals(es[i]))//o指向的对象与将nameList中遍历出来的每个元素进行对比,对比规则o.equals(es[i])——>因为o指向name变量的地址,即o里面存的为上转型对象name变量的地址,变量o是Object类型,变量name是String类型,在程序调用equals方法时会出现多态,即在编译调用Object的equals,但是执行时指向的是String类中的equals。

jdk14中equals底层代码分析

以下的例子是jdk中的Object类的equals方法,以及已经重写Object类equals方法的Integer类和String类,我们可以在程序中直接调用,但是如果要想在自定义类中实现自己想要的效果,就需要在自定义类中重写equals方法。

Object类中equals实质就是比较地址是否相同:

    public boolean equals(Object obj) {
        return (this == obj);
    }

Integer类中重写了Object类中的equals方法,其实质是比较类中存储的内容是否相同

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
          return value == ((Integer)obj).intValue();
        }
        return false;
    }

Stringr类中重写了Object类中的equals方法,其实质是比较字符串内容是否相同:

    public boolean equals(Object anObject) {
        if (this == anObject) {
          return true;
        }
        if (anObject instanceof String) {
          String aString = (String)anObject;
          if (!COMPACT_STRINGS || this.coder == aString.coder) {
            return StringLatin1.equals(value, aString.value);
          }
        }
        return false;
    }
posted @ 2021-05-11 21:09  程序新人小刘  阅读(600)  评论(0)    收藏  举报