contains方法
contains()方法
格式:对象名.contains(Object o);//Object o 为需要查找或判断的内容。
作用:判断对象中是否包含Object o,若包含,则返回true,否则返回false
代码:
public class Test {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<String>();
names.add("wjq");
System.out.println(names.contains("wjq"));//true
System.out.println(names.contains("957"));//false
}
}
不同情况下的contains方法分析
源码展示:
//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;
}
如果Object o位置对应的数据的对应类型即方法处理:
String类型的对象,则contains方法实质上调用的是String对象中的equals
基本数据类型包装类,则contains方法实质上调用的是包装类中的equals
类类型,则contains方法实质上调用的是类类型中的equals
类型一:Object o位置对应的数据String类型的对象
代码:
ArrayList<String> names = new ArrayList<String>();//限定数据为String类型
names.add("wjq");
System.out.println(names.contains("wjq"));
分析:
当.contains(Object o)中Object o对应的类型为String类,又因为Object o对应的数据为"wjq"不为null,因此进行o.equals(elementData[i])代码语句,此时contains方法调用String类中的equals方法,即比较两字符串的字符是否分别对应相等,若相等,则为真,返回i,indexOf(o)=i>=0,所以contains方法返回值为true,否则,则继续进行for循环直到for循环结束返回-1,因为indexOf(o)=(-1)<0,所以contains方法返回值为false。判断结束。
类型二:Object o位置对应的数据包装类类型的对象
代码:
ArrayList<Integer> ages = new ArrayList<Integer>();//包装类
ages.add(12);
System.out.println(ages.contains(new Integer(12)));
分析:
当.contains(Object o)中Object o对应的类型为包装类(举例为整形包装类Integer),又因为Object o对应的数据为 12 不为null,因此进行o.equals(elementData[i])代码语句,此时contains方法调用包装类中的equals方法,即比较两个数据的值是否相等,若相等,则为真,返回i,indexOf(o)=i>=0,所以contains方法返回值为true,否则,则继续进行for循环直到for循环结束返回-1,因为indexOf(o)=(-1)<0,所以contains方法返回值为false。判断结束。
类型三:Object o位置对应的数据自定义类类型的对象
代码:
ArrayList<Student> students = new ArrayList<Student>();//自定义类类型
students.add(new Student("111"));
System.out.println(students.contains(new Student("111")));
结果为:
false
上述程序运行结果为false,但显然返回值输出应该为true,这种情况出现的原因是:contains在执行时需要调用Student中的equals方法,但由于Student类中并没有equals方法,从而调用了Student的父类Object类中的equals方法,导致结果发生错误,因此我们需要对其进行重写。
重写前:
public boolean equals(Object obj) {
return (this == obj);
}
重写后:
@Override
public boolean equals(Object obj) {//o->obj
Student s = (Student) obj;//下转型
String argId = this.id;
String elementId = s.id;//elementId->elementDate[i]
return argId.equals(elementId);//多态;
//return s.id.equals(this.id);
}
分析:
重写方法后,使用强制类型转换,将Object类的obj强制转化String类,使程序执行return argId.equals(elementId); 语句时,通过String类型的argId,调用String方法中的equals。即比较两字符串的字符是否分别对应相等,若相等,则为真,返回i,indexOf(o)=i>=0,所以contains方法返回值为true,否则,则继续进行for循环直到for循环结束返回-1,因为indexOf(o)=(-1)<0,所以contains方法返回值为false。判断结束。
然而,当进行强制类型转换时,若obj不是Student类,则程序编译会发生错误且比较无意义,因此,不妨添加if条件判断语句使重写后的方法更加完整。
改良后的重写代码:
@Override
public boolean equals(Object obj) {//o->obj
if(obj instanceof Student) {//instanceof 用于判断两端的类是否相同
Student s = (Student) obj;//下转型
String argId = this.id;
String elementId = s.id;//elementId->elementDate[i]
return argId.equals(elementId);//多态;
//return s.id.equals(this.id);
} else
return false;
}
完善后的Student类代码展示:
public class Student {
private String id;
@Override
public boolean equals(Object obj) {//o->obj
if(obj instanceof Student) {//instanceof 用于判断两端的类是否相同
Student s = (Student) obj;//下转型
String argId = this.id;
String elementId = s.id;//elementId->elementDate[i]
return argId.equals(elementId);
// return s.id.equals(this.id);
} else
return false;
}
public Student(String id) {
this.id = id;
}
}