1、源码:
//contains方法
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
//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;
}
2、String类:
ArrayList<String> names = new ArrayList<String>();
names.add("Jim");
System.out.println(names.contains("Jim"));
分析:1.names.contains("Jim"):调用contains方法,形参(Object o)中的o指向String类型的对象Jim。
2.执行return indexOf(o) >= 0时调用indexOf方法,形参(Object o)中的o指向contains方法中的o,即String类型的对象Jim。
3.o!=null,执行else中的语句,o.equals(elementData[i])调用子类String类中的equals方法,比较内容是否相同,结果相 同,所以i>=0,contains方法中返回true。
3、包装类:
ArrayList<Integer> ages = new ArrayList<Integer>();
ages.add(12);
//System.out.println(ages.contains(12));//12表面上是int类型,实质上是Integer类型
System.out.println(ages.contains(new Integer(12)));
分析:1.ages.contains(new Integer(12)):调用contains方法,形参(Object o)中的o指向new Integer(12)对象。
2.执行return indexOf(o) >= 0时调用indexOf方法,形参(Object o)中的o指向contains方法中的o,即new Integer(12)对象。
3.o!=null,执行else中的语句,o.equals(elementData[i])调用子类Integer类中的equals方法,比较内容是否相同,结果相 同,所以i>=0,contains方法中返回true。
4、自定义类类型:
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student("111"));
System.out.println(students.contains(new Student("111")));
分析:1.Student类重写前:
public class Student {
private String id;
public Student(String id) {
this.id = id;
}
}
如上分析到第3步时,o调用的是父类Object的equals方法,比较地址是否相同,创建的两个对象地址不同,所以i=-1,则 contains中返回false。
2.Student类重写后:
public class Student {
private String id;
public Student(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
Student s = (Student)obj;
return this.id.equals(s.id);
/*String argId = this.id;
String elementId = s.id;
return argId.equals(elementId);*/ //等价于return this.id.equals(s.id)
}
}
同样,如上分析到第3步后,o调用的是子类Student改写后的equals方法,比较内容是否相同,创建的两个对象内容相同,所 以i>=0,则contains方法中返回true。
3.instanceof
ArrayList<Object> list = new ArrayList<Object>();
list.add(new String());
System.out.println(list.contains(new Student("111")));
将Student类型改为Object后,在执行到o.equals(elementData[i])时,o指向new Student("111"),elementData[i]指向new String()即改写的equals函数参数列表中的obj也指向new String(),然后执行“Student s = (Student)obj”时报错,因为无法将 String类型的数据转换成Student类型。
修改如下:
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student s = (Student)obj;
return this.id.equals(s.id);
/*String argId = this.id;
String elementId = s.id;
return argId.equals(elementId);*/ //等价于return this.id.equals(s.id)
}
return false;
}