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