List<String> names= new ArrayList<>();
names.add("Jimmy");
names.add("tommy");
System.out.println(names.contains("Jimmy")); //查询是否包含“Jimmy”
public boolean contains(Object o) {//此处的o即为contains方法中的参数对象,此处指“Jimmy”
return indexOf(o) >= 0;//数值>=0,返回true
}
public int indexOf(Object o) {
return indexOfRange(o, 0, size);//size指调用contains()的集合的大小
}
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData; //将集合中元素放到数组中
if (o == null) {//o为null的情况
for (int i = start; i < end; i++) {//遍历集合中的元素,直到找到集合中为null的元素为止
if (es[i] == null) {
return i;
}
}
} else {//!o == null
for (int i = start; i < end; i++) {//
if (o.equals(es[i])) {//o调用相应的equals()方法
return i;//返回找到比较成功元素的下标
}
}
}
return -1;
}
上面o(continue方法中的参数对象)调用的什么样的equals()方法取决于o是什么类型:
contains()方法中的参数类型 | 调用的equals()方法 |
---|---|
String类型 | String对象中的equals方法 |
基本数据类型的包装类 | 包装类中的equals()方法 |
类类型 | 类类型中的equals()方法 |
1.当执行到names.add("Jimmy");时,调用contains()方法,其中“Jimmy”赋值给o,o即为String类。
2.接着再调用indexof()方法,返回indexofRange()方法,因为o ! = null;所以进入else{}语句里,o去调用String里面的equals()方法(先比较地址,再比较每个字符,有一样相同即返回true),与集合中的元素进行比较,一旦找到相同的(即equals()方法返回true),则返回此时对应的i。
3.跳回contains()方法中,因此时 i>=0; 所以返回true。
学生类
public class Student {
private String id;
public Student(String id) {
super();
this.id = id;
}
public Student() {
super();
}
}
测试类
List<Student> list = new ArrayList<>();
list.add(new Student("123"));
list.add(new Student("124"));
System.out.println(list.contains(new Student("123")));
这时候返回的值为: false.
1.执行到list.contains(new Student("123"))的时候,跳转到contains()方法,创建一个Student对象“123”赋值给o,o为Student类。
2.接着再调用indexof()方法,返回indexofRange()方法,因为o ! = null;所以进入else{}语句里,o本来要调用Student类里面的equals()方法,但是Student类里面没有重写equals()方法,所以只能调用父类Objecr类里面的equals()方法,而父类Objecr类里面的equals()方法比较的是地址,我们每创建一个对象都会新开辟一个空间,即每创建一个对象都有一个新的地址,因此o的地址与集合中的每个元素的地址不一样,所以equals()方法返回的为false,跳出else语句,执行return -1;。
3.跳转回contains()方法里,最终返回false。
4.所以我们想要让contains()方法成功,就必须在Student类中重写equals()方法。
public class Student {
private String id;
public Student(String id) {
super();
this.id = id;
}
public Student() {
super();
}
@Override
public boolean equals(Object obj) {//集合中的每一个元素
if(obj instanceof Student) {//判断输入的类型是否是属于Student
Student student = (Student)obj;//下转型对象,上面进行了上转型
return this.id.equals(student.id);//o的字符与集合中每一个元素的字符进行对比。
}
return false;
}
}
重写之后再运行,结果就为true了。再次分析一下:
1.执行到list.contains(new Student("123"))的时候,跳转到contains()方法,创建一个Student对象“123”赋值给o,o为Student类。
2.接着再调用indexof()方法,返回indexofRange()方法,因为o ! = null;所以进入else{}语句里,o调用Student类里面的equals()方法,我们重写的equals()方法先比较地址,再比较字符,有一个成立则返回true,条件满足进入if语句,执行return i;。
3.跳回contains()方法中,因此时 i>=0; 所以返回true。
原文:https://www.cnblogs.com/imetal/p/14756917.html