源码:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
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;
}
1、String类型:
ArrayList<String> names=new ArrayList<String>();
names.add("Jim");
System.out.println(names.contains("Jim"));
分析:
此时“Jim”是contains和indexOf方法里的Object类型的o。当o不为空时,执行else代码块里的内容,将o与存储的数据elementData相比较,这里的elementData就是names调用方法add添加的内容
2、包装类:
ArrayList<Integer> age=new ArrayList<Integer>();
age.add(12);
System.out.println(age.contains(new Integer(12)));
分析:
此时在indexOf方法里执行的是Integer类的equals方法
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
此时obj是age调用add方法添加的12这个对象,如果obj是Integer类的对象,则将obj与contains方法中创建的对象相比较,如果是Integer类的子类或是接口的实现类,则将obj强制换成Integer类,再进行比较
3、自定义类类型:
ArrayList<Student> names=new ArrayList<Student>();
names.add(new Student("111"));
System.out.println(names.contains(new Student("111")));
分析:
(1)重写前:调用的是Object类中的 equals方法,而Object中的equals方法是比较地址的
public boolean equals(Object obj) {
return (this == obj);
}
(2)重写后:调用的是自定义类中重写的equals方法
@Override
public boolean equals(Object obj) {
Student s=(Student)obj;
return this.id.equals(s.id);
}
(3)加instanceOf:
当是如下情况时:
ArrayList<Object> names=new ArrayList<Object>();
names.add(new String("111"));
System.out.println(names.contains(new Student("111")));
String类型是不能与Student类型数据相比较的
所以,重写的equals方法应如下:
@Override
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student s=(Student)obj;
String argId=this.id;
String elementId=s.id;
return argId.equals(elementId);
}
return false;
}
分析:
先判断存储添加的数据是否是Student类型或Student子类类型,如果是才进行比较。