首页 > 其他 > 详细

ArrayList底层实现contains方法的原理。

时间:2021-05-11 21:56:46      阅读:19      评论:0      收藏:0      [点我收藏+]

List实现类ArrayList底层实现contains()的原理

实验代码

List<String> names= new ArrayList<>();
   names.add("Jimmy");
   names.add("tommy");
   System.out.println(names.contains("Jimmy")); //查询是否包含“Jimmy”

contains()源码

public boolean contains(Object o) {//此处的o即为contains方法中的参数对象,此处指“Jimmy”
        return indexOf(o) >= 0;//数值>=0,返回true
    }

public int indexOf(Object o) {
        return indexOfRange(o, 0, size);//size指调用contains()的集合的大小
    }

    int indexOfRange(Object o, int start, int end) {
        Object[] es = elementData; //将集合中元素放到数组中
        if (o == null) {//o为null的情况
            for (int i = start; i < end; i++) {//遍历集合中的元素,直到找到集合中为null的元素为止
                if (es[i] == null) {
                    return i;
                }
            }
        } else {//!o == null
            for (int i = start; i < end; i++) {//
                if (o.equals(es[i])) {//o调用相应的equals()方法
                    return i;//返回找到比较成功元素的下标
                }
            }
        }
        return -1;
    }

上面o(continue方法中的参数对象)调用的什么样的equals()方法取决于o是什么类型:

contains()方法中的参数类型 调用的equals()方法
String类型 String对象中的equals方法
基本数据类型的包装类 包装类中的equals()方法
类类型 类类型中的equals()方法

分析实现代码的运行过程

1.当执行到names.add("Jimmy");时,调用contains()方法,其中“Jimmy”赋值给o,o即为String类。

2.接着再调用indexof()方法,返回indexofRange()方法,因为o ! = null;所以进入else{}语句里,o去调用String里面的equals()方法(先比较地址,再比较每个字符,有一样相同即返回true),与集合中的元素进行比较,一旦找到相同的(即equals()方法返回true),则返回此时对应的i。

3.跳回contains()方法中,因此时 i>=0; 所以返回true。

自定义类类型

学生类

public class Student {
	private String id;
	public Student(String id) {
		super();
		this.id = id;
	}
	public Student() {
		super();
	}	

}

测试类

List<Student> list = new ArrayList<>();
list.add(new Student("123"));
list.add(new Student("124"));   
  System.out.println(list.contains(new Student("123")));
		

分析实现代码的运行过程

这时候返回的值为: false.

1.执行到list.contains(new Student("123"))的时候,跳转到contains()方法,创建一个Student对象“123”赋值给o,o为Student类。

2.接着再调用indexof()方法,返回indexofRange()方法,因为o ! = null;所以进入else{}语句里,o本来要调用Student类里面的equals()方法,但是Student类里面没有重写equals()方法,所以只能调用父类Objecr类里面的equals()方法,而父类Objecr类里面的equals()方法比较的是地址,我们每创建一个对象都会新开辟一个空间,即每创建一个对象都有一个新的地址,因此o的地址与集合中的每个元素的地址不一样,所以equals()方法返回的为false,跳出else语句,执行return -1;。

3.跳转回contains()方法里,最终返回false。

4.所以我们想要让contains()方法成功,就必须在Student类中重写equals()方法。

重写equals()方法

public class Student {
	private String id;
	public Student(String id) {
		super();
		this.id = id;
	}
	public Student() {
		super();
	}	
		@Override
	public boolean equals(Object obj) {//集合中的每一个元素
		if(obj instanceof Student) {//判断输入的类型是否是属于Student
			Student student = (Student)obj;//下转型对象,上面进行了上转型
			return this.id.equals(student.id);//o的字符与集合中每一个元素的字符进行对比。
		}
		return false;
	}
	
}

重写之后再运行,结果就为true了。再次分析一下:

1.执行到list.contains(new Student("123"))的时候,跳转到contains()方法,创建一个Student对象“123”赋值给o,o为Student类。

2.接着再调用indexof()方法,返回indexofRange()方法,因为o ! = null;所以进入else{}语句里,o调用Student类里面的equals()方法,我们重写的equals()方法先比较地址,再比较字符,有一个成立则返回true,条件满足进入if语句,执行return i;。

3.跳回contains()方法中,因此时 i>=0; 所以返回true。

ArrayList底层实现contains方法的原理。

原文:https://www.cnblogs.com/imetal/p/14756917.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!