简述contains的底层实现

举例String的contains底层:

main方法:

List<String> names= new ArrayList<>();
names.add("Jimmy");
System.out.println(names.contains("Jimmy"));

contains源码:

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

immy传入到contains方法中的参数,即o指向Jimmy所指向的对象,o为上转型对象

indexof 源码:

public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

​ indexof方法流程:判断o是否为null。如果是null,则循环if(jimmy ==null),如果找到,将index赋值为找到的地址,则返回index。
​ 因为Jimmy不是null,则for循环遍历names中每一个元素;其中size为全局变量,实质为this.size,意思是names的元素个数。让Jimmy和数组中的每一个元素进行比较。如果找到,返回i下标,则返回index。找不到就返回-1。
​ 由题知,names为一个上转型对象,运行时会调用ArrayList里的已有的equals方法。

string的equal源码

public boolean equals(Object anObject) {
	if (this == anObject) {// 如果是同一个对象,返回true
		return true;
	}
	if (anObject instanceof String) { // 判断是否是string对象
		String anotherString = (String) anObject;
		int n = value.length;
		if (n == anotherString.value.length) {// 判断长度是否一致
			char v1[] = value;
			char v2[] = anotherString.value;
			int i = 0;
			while (n != 0) {
				if (v1[i] != v2[i])// 比较每个字符是否一样
					return false;
				i++;
			}
			return true;
		}
	}
	return false;
}

​ ArrayList里的equals方法流程:1.判断与Jimmy比较的name中的元素的类型是否为String或者子类,如果不同,则返回false,如果相同,执行String的equals。
因为String的equals只判断字符是否相同,所以输出结果为true。

举例自定义的contains底层:

定义student:

public class Student {
	String id;
@Override
public Student(String id) {
	super();
	this.id = id;
	}

main方法:

List<Student> list = new ArrayList<>();
list.add(new Student("110"));
System.out.println(list.contains(new Student("110")));

contains源码:

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

new Student("110")传入到contains方法中的参数,即指向new Student("110")所指向的对象,new Student("110")为上转型对象

indexof源码:

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;
}

object的equals的源码:

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

因为如果运行上图,因为Student没有equals方法,则会调用object的equals方法,object比较地址是否相同,不能很好的实现我们想要的结果,使用需要重写Student的equals方法。

重写equals方法:

public boolean equals(Object obj) {
	if (obj instanceof Student) {
		Student student = (Student) obj;
		return this.id.equals(student.id);
	}
	return false;
}

这里obj是一个上转型对象,将new Student("110")判断是否为Student,如果没有这步,这可能出现类型转化错误,然后将obj下转型,这样才能调用Student的方法。最后将names的值的id和110进行比较,返回一个true或者flase。

posted @ 2021-05-11 22:54  如烟成雨  阅读(259)  评论(0编辑  收藏  举报