contains()方法可以用来判断集合中是否含有某元素,若有则返回true,没有则返回false。
contains()源码: public boolean contains(Object o) { //此处的o即为contains方法中的参数对象 return indexOf(o) >= 0;//如果数值>=0,则返回true}public int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i]==null)//elementDate[i]:去遍历集合中的元素 一直到找到集合中为null的元素为止(在for循环满足的条件下)return i;} else {// o != null时for (int i = 0; i < size; i++)if (o.equals(elementData[i]))//o(即contains方法中的参数对象)调用相应的equals()方法return i;}return -1;}上面o(即contains方法中的参数对象)调用的什么样的equals()方法取决于o是什么类型:
contains()方法中的参数类型调用的equals()方法String类型String对象中的equals()方法基本数据类型的包装类包装类中的equals()方法类类型类类型中的equals()方法String类型: import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<String> names = new ArrayList<String>();names.add("zxdmn");names.add("xrpdsn");System.out.println(names.contains("xrpdsn"));}}这时输出的结果肯定是:true
让我们来分析一下其中的判断过程是怎样的:
输出的结果为:true
我们再来分析一下:
ages.contains(12)里的12看似是int类型,实则进行了隐形转换,相当于ages.contains(new Integer(12))
先定义一个Student类:
public class Student {private String id;//学号public Student(String id){this.id = id;}} import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<Student> students = new ArrayList<Student>();students.add(new Student("2019"));students.add(new Student("2020"));System.out.println(students.contains(new Student("2020")));}}这时候返回的是:false
为什么呢?集合中有学号为"2020"的学生呀,为什么不返回true呢?让我们来深入分析一下:
我们知道学生的学号是唯一的,所以上述查到学号为"2020"的学生时应返回true,那么怎么做呢?这时就要重写父类中的equals()方法,使其满足我们现实生活中的逻辑, public class Student {private String id;//学号public Student(String id){this.id = id;}public boolean equals(Object obj) {//obj就是集合中的每一个元素Student s = (Student)obj;//需要下转型,因为上一行obj上转型了return this.id.equals(s.id);//谁调用equals()方法,this就指谁,这里是o(即contains方法中的参数对象)}} import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<Student> students = new ArrayList<Student>();students.add(new Student("2019"));students.add(new Student("2020"));System.out.println(students.contains(new Student("2020")));}}
这次返回的结果就是:true了,让我们再来分析一下:
当代码执行到students.contains(new Student("2020"))时,跳转到contains()方法,(请看contains()源码),创建的一个新的对象"2020"赋给o,因此o属于Student类,再调用indexOf()方法,因为o!=null,所以进入else语句中,然后o去调用Student中的equals()方法,而我们这里定义的这个equals()方法也是先比较地址,再比较字符,其中一项一样,即返回true,所以条件满足,进入if语句,执行return i;,再跳转回contains()方法中,此时i>=0,所以最终返回true补充一点:跟上面第4点一样 在重写equals()中使用 instanceof:仔细看上面的代码是有bug的,因为一个集合只能放泛型规定的东西,若此时用contains()方法来辨别一个东西是否属于该集合(即是否有一个元素与该东西相同),若该东西不属于泛型之内,则代码会报错,而不是返回false,这时我们就需要instanceof来辨别出要判断的东西是否属于某一类东西,从而让代码更加人性化:
其中 instanceof 的作用是:测试它左边的对象是不是属于右边的类的实例,若是返回true,若不是则返回false
注意:此时的泛型变为<Object>,不再是<Student>
import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<Object> list = new ArrayList<Object>();list.add(new String("123"));list.add(new Student("2020"));System.out.println(list.contains(new Student("2020")));}}这时返回的结果就是true了,若没有instanceof先来判断一下,则代码会报错,因为"123"与Student无任何关系,不能进行强制类型转换(也就是下转型)所以会报错,让我们来具体分析一下:
代码执行到list.contains(new Student("2020"))时,调用contains()方法,(请看contains()源码), 新创建的Student对象"2020"会赋给o,因此o为Student类,再调用indexOf()方法,因为o!=null,所以进入else语句中,o调用Student中的equals()方法,然后执行obj instanceof Student,判断obj(即集合中的各个元素,直到找到或循环停止为止)中的元素是否属于Student类,再做进一步判定,若不是Student类,则直接执行return false;,若属于Student类,再判定其地址、字符是否与obj中的某个元素相同,若有一样相同,则返回true,若都不同,则返回false,最后再返回到contains()方法中,输出相应的boolean逻辑值,此例最后返回的是true补充一点:若o=null,则与上述相同。